awd兼具sed的所有功能,而且比sed更加强大。
awk '[条件1]{动作1}[条件2]{动作2}......' filename
测试文件test的内容如下:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
截取文档中的指定段
以“:”为分隔符取出test文件中的第5和第7列
$awk -F ':' '{print $5 "\t" $7}' test
root /bin/bash
daemon /usr/sbin/nologin
bin /usr/sbin/nologin
-F 是指定分隔符,本例中是“:”,若不指定分隔符,则默认为空格或Tab。
print为打印动作,$5和$7表示第5段和第7段,“\t”为制表符。在这里动作需要用{}括起来。
也可使用printf命令,它与print命令的区别就是:print命令自带换行(\n),而printf命令若要换行需要在格式末尾加上换行符(\n)。
注意:$n表示第n段,$0表示一整行。在打印的格式中可以自定义字符串,例如:
$awk -F ':' '{print \$5 " :::: " \$7}' test
root :::: /bin/bash
daemon :::: /usr/sbin/nologin
bin :::: /usr/sbin/nologin
BEGIN命令
在进行一个动作之前,先执行一个动作(BEGIN指定的动作)。
例如在执行上述动作之前先输出“This is a test.”字符串。
$awk -F ':' 'BEGIN{print "This is a test."}{print $5"\t"$7}' test
This is a test.
root /bin/bash
daemon /usr/sbin/nologin
bin /usr/sbin/nologin
也可以在BEGIN里面指定分隔符(常用):
$awk 'BEGIN{FS=":"}{print $5"\t"$7}' test
root /bin/bash
daemon /usr/sbin/nologin
bin /usr/sbin/nologin
END命令
与BEGIN命令相似
匹配字符或者字符串
#匹配包含“sbin”的行
$awk '/sbin/' test
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
#匹配出第7列中包含“sbin”的行
$awk -F ':' '$7 ~/sbin/' test
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
#此处"~"就是匹配的意思
#找出第一列为“root”的行的第7列的值
$awk -F ':' '$1 ~/root/{print $7}' test
/bin/bash
条件操作符
awk中可以用逻辑符号进行判断,如:==,>,>=,<,<=,!=等。需要注意的是比较数字时,数字不能用双引号引起来,否则会被认为是字符串。
#打印第3列的值大于1的行
$awk 'BEGIN{FS=":"}$3>1' test
bin:x:2:2:bin:/bin:/usr/sbin/nologin
#若1引用双引号就会编程字符串
$awk 'BEGIN{FS=":"}$3>"1"' test
bin:x:2:2:bin:/bin:/usr/sbin/nologin
为什么输出结果是一样的呢?再看一例
$awk 'BEGIN{FS=":"}$3>"10"' test
bin:x:2:2:bin:/bin:/usr/sbin/nologin
为什么结果还是一样的呢?
那是因为引号引起来的是字符串,而字符串的比较是按ASCII值比较的。本例中的参比较值为10,但2的ASCII值已经大于1的ASCII值,所有结果还是一样。由此可见,数字的比较和数字字符串的比较区别还是很大的。
可以比较不同的段,也可以使用&&和||。
awk内置变量
awk常用的变量有NF和NR,NF表示用分隔符分隔后一共有多少段,NR表示行号。
这里的NF和NR相当于自定义的变量,可以用来进行计算和比较。
NF
$awk -F ':' '{print NF}' test
7
7
7
#test文件中每行有7个段,
$awk -F ':' '{print $NF}' test #输出具体的变量值
/bin/bash
/usr/sbin/nologin
/usr/sbin/nologin
NR
#打印前两行
$awk 'NR<3' test
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
NR变量可以用来进行匹配。
awk中的数学运算
#更改段值,将第5段的值更改为root
$awk 'BEGIN{FS=":"} $5="root"' test
root x 0 0 root /root /bin/bash
daemon x 1 1 root /usr/sbin /usr/sbin/nologin
bin x 2 2 root /bin /usr/sbin/nologin
#计算第3段所有值的和
$awk 'BEGIN{FS=":"}{(sum=sum+$3)}END{print sum}' test
3
在awk中可以使用if判断、for循环等。
$awk -F ':' '{if($1=="root") print $0}' test
root:x:0:0:root:/root:/bin/bash