AWK简单使用方法

栏目: 服务器 · 发布时间: 7年前

内容简介:length([s]):统计s的字符数量;sub(r,s):将当前行中最左边第一个能被r匹配的内容,替换成s;

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分隔符,默认是\n;
ORS:输入文件record分隔符,默认是\n;
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@<a href="https://www.linuxidc.com/topicnews.aspx?tid=14" target="_blank" title="CentOS">CentOS</a>7 ~]# 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\n",$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\n",$1}' /etc/passwd
Allen
logstash

例如:当$3大于等于1000时,打印为CommonUser: $1;否则打印为Systemuser: $1;
[Allen@centos7 ~]$ awk -F: '{if($3>=1000) {printf "CommonUser: %-15s\n",$1} else {printf "SystemUser: %s\n",$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次或多次,后跟 linux 16的行,以空格为分隔符,显示每行中各字段的长度;
[Allen@centos7 ~]$ sudo awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {printf "%-55s%i\n",$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\n",$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\n",$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

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址: https://www.linuxidc.com/Linux/2018-12/155639.htm


以上所述就是小编给大家介绍的《AWK简单使用方法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Essential ActionScript 3.0

Essential ActionScript 3.0

Colin Moock / Adobe Dev Library / June 22, 2007 / $34.64

ActionScript 3.0 is a huge upgrade to Flash's programming language. The enhancements to ActionScript's performance, feature set, ease of use, cleanliness, and sophistication are considerable. Essentia......一起来看看 《Essential ActionScript 3.0》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具