zoukankan      html  css  js  c++  java
  • AWK简单使用方法

    1. 命令格式

    gawk [OPTIONS] 'program' FILES....
    program:'PATTERN{ACTION}'
    	一条awk命令中,PATTERN和ACTION,至少存在一个才可执行;
    		缺少PATTERN,则对输入行内容全部执行ACTION;
    		缺少ACTION,则所有匹配上PATTERN的输入行都会被输出;
    	在awk中使用分号“;”来分割语句;
    

    2. awk的执行过程

    awk读取一行,进行模式匹配,匹配了就执行相应的动作,没有匹配就忽略,读取下一行,重复此动作.

    3. 内置变量

    FS:输入文件的field分隔符,默认是空白字符;
    OFS:输出文件的field分隔符,默认是空白字符;
    RS:输入文件record分隔符,默认是
    ;
    ORS:输入文件record分隔符,默认是
    ;
    NF:每行的field数量,{print NF}表示显示当前行的field数量,{print $NF}表示显示当前行的最后一个field;
    NR:record数,对所有输入行进行统一排序;
    FNR:record数,对每个文件的输入行进行分别排序;
    FILENAME:输入文件的名字;
    ARGC:命令行中的参数个数;
    ARGV:数组,可以将当前命令行中的参数分别加入到ARGV这个数组中,从0开始;
    $1、$2、$3...$n:代表当前行中对应的field
    

    4. 常用OPTION

    -F:指定输入分隔符;
    -v:指定awk的变量;像FS、OSF、RS、ORS这些变量,就可以使用-v进行重新赋值;
    

    5. 双引号的作用

    定义一个变量superuser的值为root,但是打印的时候,发现打印出了一个空行,并没有实际内容
    [root@centos7 ~]# awk 'BEGIN{superuser=root;print superuser}'
    空行......
    
    这是因为只有加上了双引号才会被awk认为是字符串,否则会被认为是变量。在上面这个例子中,想要为superuser赋值的是root字符串,但是因为没有加上双引号,被awk认为root也是一个变量,但是awk中又不存在这个变量,所以最终为superuser的变量内容就是空。
    所以在awk中定义变量应该是这种情况:
    [root@centos7 ~]# awk 'BEGIN{superuser="root";print superuser}'
    root
    
    使用-v参数就没有上面的限制
    [root@centos7 ~]# awk -v superuser=root 'BEGIN{print superuser}'
    root
    

    6. ACTION

    6.1 printf命令:按照指定的FORMAT进行格式化输出;

    格式化输出:printf FORMAT, item1, item2, ...
    FORMAT:FORMAT是一个字符串, 它包含按字面打印的文本, 中间散布着格式说明符, 格式说明符用于说明如何打印值. 一个格式说明符是一个%, 后面跟着几个字符, 这些字符控制一个value 的输出格式. 第一个格式说明符说明item1 的输出格式, 第二个格式说明符说明item2 的输出格式, 依次类推. 于是, 格式说明符的数量应该和被打印的item 一样多;
    
    printf不会自动产生换行符,必须手动创建;
    

    格式符

    %s:显示字符串;
    %i,%d:显示十进制整数;
    

    修饰符

    #[.#]:第一个#控制显示的宽度,第二个#表示小数点后的精度;
    	例如:%3.1f
    -减号:左对齐(不加减号,默认为右对齐);
    +加号:显示数值的符号;
    

    实例

    例如:使用printf打印/etc/passwd中的$1和$3
    [Allen@centos7 ~]$ head /etc/passwd | awk -F: '{printf "Username: %-12sUID: %-8i
    ",$1,$3}'
    Username: root        UID: 0       
    Username: bin         UID: 1       
    Username: daemon      UID: 2       
    Username: adm         UID: 3       
    Username: lp          UID: 4       
    Username: sync        UID: 5       
    Username: shutdown    UID: 6       
    Username: halt        UID: 7       
    Username: mail        UID: 8       
    Username: operator    UID: 11       
    

    6.2 if-else

    语法:'if(condition){statements}[else{statements}]'
    使用场景:对awk取得的整行或某个字段做条件判断;
    

    实例

    例如:当$3大于等于1000时,打印$1;
    [Allen@centos7 ~]$ awk -F: '{if($3>=1000) printf "%s
    ",$1}' /etc/passwd
    Allen
    logstash
    
    例如:当$3大于等于1000时,打印为CommonUser: $1;否则打印为Systemuser: $1;
    [Allen@centos7 ~]$ awk -F: '{if($3>=1000) {printf "CommonUser: %-15s
    ",$1} else {printf "SystemUser: %s
    ",$1}}' /etc/passwd | head 
    SystemUser: root
    SystemUser: bin
    SystemUser: daemon
    SystemUser: adm
    SystemUser: lp
    SystemUser: sync
    SystemUser: shutdown
    SystemUser: halt
    SystemUser: mail
    SystemUser: operator
    

    6.3 while

    语法:while(condition){statements}
    使用场景:对一行内的多个字段逐一进行类似处理时使用;或对数组中的各元素逐一处理时使用;
    

    实例

    例如:以空格开头0次或多次,后跟linux16的行,以空格为分隔符,显示每行中各字段的长度;
    [Allen@centos7 ~]$ sudo awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {printf "%-55s%i
    ",$i,length($i); i++}}' /boot/grub2/grub.cfg
    linux16                                                7
    /vmlinuz-4.18.14-1.el7                                 22
    root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f         46
    ro                                                     2
    rhgb                                                   4
    quiet                                                  5
    linux16                                                7
    /vmlinuz-3.10.0-693.el7.x86_64                         30
    root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f         46
    ro                                                     2
    rhgb                                                   4
    quiet                                                  5
    
    例如:以空格开头0次或多次,后跟linux16的行,以空格为分隔符,只显示每行中字段的长度>=7的字段;
    [Allen@centos7 ~]$ sudo awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {printf "%-55s%i
    ",$i,length($i)}; i++}}' /boot/grub2/grub.cfg
    linux16                                                7
    /vmlinuz-4.18.14-1.el7                                 22
    root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f         46
    linux16                                                7
    /vmlinuz-3.10.0-693.el7.x86_64                         30
    root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f         46
    

    6.4 for

    语法:for(expr1;expr2;expr3) statement
    特殊用法:for(var in arry) statements		##用于遍历数组中的元素
    

    实例

    例如:以空格开头0次或多次,后跟linux16的行,以空格为分隔符,显示每行中各字段的长度;
    [Allen@centos7 ~]$ sudo awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) printf "%-55s%i
    ",$i,length($i)}' /etc/grub2.cfg 
    linux16                                                7
    /vmlinuz-4.18.14-1.el7                                 22
    root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f         46
    ro                                                     2
    rhgb                                                   4
    quiet                                                  5
    linux16                                                7
    /vmlinuz-3.10.0-693.el7.x86_64                         30
    root=UUID=2073d1d0-1eab-4a58-900e-b9bfd178278f         46
    ro                                                     2
    rhgb                                                   4
    quiet                                                  5
    

    7. 描述awk函数示例(至少3例)

    length([s]):统计s的字符数量;
    sub(r,s):将当前行中最左边第一个能被r匹配的内容,替换成s;
    sub(r,s,t):将t中最左边第一个能被r匹配的内容,替换成s;
    gsub(r,s):将当前行中能被r匹配的内容,全部替换成s;
    gsub(r,s,t ):将t中能被r匹配的内容,全部替换成s;
    split(s,a):将s分割,然后分别加入到数组a中(awk命令中没有指定FS则使用默认的空格做为分隔符);
    split(s,a,fs):使用fs将s分割,然后分别加入到数组a中;
    sprintf(format,expr1,expr2,exprn):返回一个字符串(不打印),这个字符串按指定的format格式化expr1..exprn
    genline:读取下一行,重新设定NF、NR、FNR;

    实例

    实例1:length函数
    [root@centos7 ~]# awk 'BEGIN{superuser="root";print length(superuser)}'
    4
    
    实例2:sub和gsub函数
    [root@centos7 ~]# echo "hello World" | awk '{sub("l",1);print $0}'
    he1lo World
    [root@centos7 ~]# echo "hello World" | awk '{sub("l",1,$1);print $0}'
    he1lo World
    
    [root@centos7 ~]# echo "hello World" | awk '{gsub("l",1);print $0}'
    he11o Wor1d
    [root@centos7 ~]# echo "hello World" | awk '{gsub("l",1,$1);print $0}'
    he11o World
    
    实例3:split函数
    数组下标从1开始
    [root@centos7 ~]# awk -F/ 'BEGIN{i="China/America/Britain";split(i,countrys);for(c=1;c<=3;c++)print countrys[c]}'
    China
    America
    Britain
    [root@centos7 ~]# awk 'BEGIN{i="China/America/Britain";split(i,countrys,"/");for(c=1;c<=3;c++)print countrys[c]}'
    China
    America
    Britain
    
    实例4:sprintf函数
    [root@centos7 ~]# awk -F: 'NR>=1&&NR<=5{x=sprintf("%-10s%-5d",$1,$3);print x}' /etc/passwd
    root      0    
    bin       1    
    daemon    2    
    adm       3    
    lp        4  
    
    实例5:getline函数
    打印出从1到10之间的偶数
    awk首先读取到了第一行,就是1,然后getline,就得到了1下面的第二行,就是2,因为getline之后,awk会改变对应的NF,NR,FNR和$0等内部变量,所以此时的$0的值就不再是1,而是2了,然后将它打印出来。以此类推,就可以得到下面的结果。
    [Allen@centos7 ~]$ seq 10 | awk '{getline; print $0}'
    2
    4
    6
    8
    10
    
    打印出从1到10之间的奇数
    因为getline在print $0之后,此时的$0仍然是第一行。然后getline,$0变成了下一行2。依次类推,就打印出了奇数行。
    [Allen@centos7 ~]$ seq 10 | awk '{print $0; getline}'
    1
    3
    5
    7
    9
    
  • 相关阅读:
    vue开发chrome扩展,数据通过storage对象获取
    Vue手动集成less预编译器
    Google Translate寻找之旅
    Javascript Range对象的学习
    Javascript Promises学习
    SublimeText 建立构建Node js系统
    We're sorry but demo3 doesn't work properly without JavaScript enabled. Please enable it to continue.
    npm安装包出现UNMET DEPENDENCY报错
    (转载)命令行说明中格式 尖括号 中括号的含义
    Linux重启网卡服务Failed to start LSB: Bring up/down networking.
  • 原文地址:https://www.cnblogs.com/jzbgltb/p/9895397.html
Copyright © 2011-2022 走看看