awk: 流式编辑器,针对文档的行来操作,awk兼有sed的所有功能,
awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。
awk的应用:
语法: awk '{print $n}' filename #n表示数字,当n=0时,代表整个文档,n=1,2,3则代表相应列:
1、打印文档中的某个段(不指定分隔符,默认已空格或空白字符分割):
[root@localhost awk]# awk -F ':' '{print $1}' test.txt|head -n5 #以“:”为分割打印第一段:
root
bin
daemon
adm
lp
[root@localhost awk]# awk -F ':' '{print $1,$3,$5}' test.txt|head -n5 #“:”为分割打印第一 三 五段:
root 0 root
bin 1 bin
daemon 2 daemon
adm 3 adm
lp 4 lp
[root@localhost awk]# awk -F ':' '{print $1"#"$3"#"$5}' test.txt|head -n5 #自定义“#”为分隔符:
root#0#root
bin#1#bin
daemon#2#daemon
adm#3#adm
lp#4#lp
注意:只能识别指定的分隔符,如果该行未指定分隔符则会打印其整行:
2、awk的匹配功能:也支持正则"+ ? ." ‘/root/’ '$1~/root/'
[root@localhost awk]# awk -F ':' '/oo/' test.txt #匹配test.txt文档中包含oo的行:
root:x:0:0:root:/root:/bin/bash
roobin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/noooologin
adm:x:3:4:adm:/var/adm:/sbin/noologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nooologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
[root@localhost awk]# awk -F ':' '$1~/root/' test.txt #匹配第一段中包含root的行:
root:x:0:0:root:/root:/bin/bash
[root@localhost awk]# awk -F ':' '$1~/ro+/' test.txt #加号表示一次或多次:
root:x:0:0:root:/root:/bin/bash
roobin:x:1:1:bin:/bin:/sbin/nologin
systemd-bus-proxy:x:999:997:systemd bus proxy:/:/sbin/nologin
[root@localhost awk]# awk -F ':' '$1~/ro?/' test.txt #问号表示零次或一次:
root:x:0:0:root:/root:/bin/bash
roobin:x:1:1:bin:/bin:/sbin/nologin
systemd-bus-proxy:x:999:997:systemd bus proxy:/:/sbin/nologin
systemd-network:x:998:996:systemd network management:/:/sbin/nologin
[root@localhost awk]# awk -F ':' '{OFS="#"} /root/ {print $1,$3,$5} /bus/ {print $0}' test.txt
#表示以”#“号为分隔符,打印匹配root和bus的行,只显示第一 三 五行:
root#0#root
root-bus-proxy#999#systemd bus proxy
root-bus-proxy:x:999:997:systemd bus proxy:/:/sbin/nologin
dbus:x:81:81:system message bus:/:/sbin/nologin
[root@localhost awk]# awk -F ':' '/root|bus/ {print $0}' test.txt #同上用法相同:
root:x:0:0:root:/root:/bin/bash
root-bus-proxy:x:999:997:systemd bus proxy:/:/sbin/nologin
dbus:x:81:81:system message bus:/:/sbin/nologin
注意:'{print $0}'则表示匹配出的所有段的内容:
如上两种相同的用法,只是匹配方式还是有差别的:
图例awk -F ':' '{OFS="#"} /root/ {print $1,$3,$5} /bus/ {print $0}' test.txt 这条命令则表示会匹配两次,并输出两次:
等于:awk -F ':' '/root/ {print $0} /bus/ {print $0}' test.txt
图例awk -F ':' '/root|bus/ {print $0}' test.txt 则会表示一次性匹配,只匹配一次:
3、awk针对数值表达式的用法: == >= <+ !=
#当‘$3==1000 {print $1}’时:
[root@localhost awk]# awk -F ':' '$3>=1000 {print $1}' test.txt
yuanhh
#当‘$3==“1000” {print $1}’时:
[root@localhost awk]# awk -F ':' '$3>="1000" {print $1}' test.txt|head -n3
root-bus-proxy
daemon
adm
#匹配字符串:需要加双引号: !=表示不等于:
[root@localhost awk]# awk -F ':' '$7!="/sbin/nologin"' test.txt
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/noooologin
adm:x:3:4:adm:/var/adm:/sbin/noologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nooologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
注释:当1000加上双引号时会被当做字符串,以ASCII码(二进制)方式计算处理,不加引号则会被当成数值来处理:
#如果不手动指定分隔符,则默认以空格为分隔符:
[root@localhost awk]# head -n3 test.txt|awk -F ':' '{OFS=":"} $1="root"'
root:x:0:0:root:/root:/bin/bash
root:x:1:1:bin:/bin:/sbin/nologin
root:x:999:997:systemd bus proxy:/:/sbin/nologin
[root@localhost awk]# awk -F ':' '$1=="root" {print $0}' test.txt #打印$1字段为root的整行:
root:x:0:0:root:/root:/bin/bash
注意:当使用一个"="等号时表示为等号前面字符赋值,使用两个等号"=="时表示逻辑关系(进行判断):
4、字符比较大小: > < >= <= !=
[root@localhost awk]# awk -F ':' '$3>$4' test.txt #输出$3大于$4的行:
root-bus-proxy:x:999:997:systemd bus proxy:/:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
systemd-network:x:998:996:systemd network management:/:/sbin/nologin
polkitd:x:997:995:user for polkitd:/:/sbin/nologin
[root@localhost awk]# awk -F ':' '$3==$4' test.txt #输出$3等于$4的行:
root:x:0:0:root:/root:/bin/bash
roobin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/noooologin
nobody:x:99:99:nobody:/:/sbin/nologin
avahi-autoipd:x:170:170:avahi ipv4ll stack:/var/lib/avahi-autoipd:/sbin/nologin
&&表示并且的意思:
[root@localhost awk]# awk -F ':' '$3>"5" && $5<"7"' test.txt
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
#当然,也存在加不加双引号的问题:则是以ASCII码比较还是以数字的方式比较:
||表示或者的意思:
[root@localhost awk]# awk -F ':' '$3>1000 || $7=="/bin/bash"' test.txt
root:x:0:0:root:/root:/bin/bash
yuanhh:x:1000:1000::/home/yuanhh:/bin/bash
[root@localhost awk]# awk -F ':' '$3>1000 || $7!="/sbin/nologin"' test.txt
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/noooologin
adm:x:3:4:adm:/var/adm:/sbin/noologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nooologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
5、输出时指定分隔符: ‘{OPS="#"}’ "#”可以是任意符号,指定分隔符:
语法一:
[root@localhost awk]# awk -F ':' '{OFS="#"} $3>1000 || $7!="/sbin/nologin" {print $1,$3,$5}' test.txt
root#0#root
daemon#2#daemon
adm#3#adm
[root@localhost awk]# awk -F ':' '{OFS="#"} {print $1,$3,$5}' test.txt|head -n3
root#0#root
roobin#1#bin
root-bus-proxy#999#systemd bus proxy
语法二:
[root@localhost awk]# awk -F ':' '{OFS="#"} {if ($3>1000 || $7=="/bin/bash") {print $1,$3,$5}}' test.txt
root#0#root
yuanhh#1000#
[root@localhost awk]# awk -F ':' '{OFS="#"} {if ($3>=1000) {print $1,$3,$5}}' test.txt
yuanhh#1000#
6、NR表示行号:===number row 表示行号:
[root@localhost awk]# awk -F ':' '{print $NR}' test.txt #NR表示行:
root
x
999
2
adm
/var/spool/lpd
/bin/sync
[root@localhost awk]# awk -F ':' '{print NR":"$0}' test.txt |head -n3 #打印前三行:
1:root:x:0:0:root:/root:/bin/bash
2:roobin:x:1:1:bin:/bin:/sbin/nologin
3:root-bus-proxy:x:999:997:systemd bus proxy:/:/sbin/nologin
[root@localhost awk]# awk -F ':' '$3>$5 {print NR":"$1}' test.txt ¥打印$3>$5的第一段:
19:postfix
21:ntp
23:tcpdump
24:yuanhh
[root@localhost awk]# awk -F ':' 'NR<=3 && $1~/root/' test.txt #使用并且:
root:x:0:0:root:/root:/bin/bash
root-bus-proxy:x:999:997:systemd bus proxy:/:/sbin/nologin
[root@localhost awk]# awk -F ':' 'NR<=3 || $1~/root/' test.txt #使用或者:
root:x:0:0:root:/root:/bin/bash
roobin:x:1:1:bin:/bin:/sbin/nologin
root-bus-proxy:x:999:997:systemd bus proxy:/:/sbin/nologin
注意:类似于grep -n:
7、NF表示行:===number fragment表示段数,列
[root@localhost awk]# awk -F ':' '$3>$5 && $7!=/sbin/nologin {print NF":"$1}' test.txt
7:postfix
7:ntp
7:tcpdump
7:yuanhh
8、求和: '{(tot=tot+$3)};END {print $tot}'
[root@localhost awk]# awk -F ':' '{(tot=tot+$3)};END {print tot}' test.txt #$3循环相加:
4766
$0表示打印整行:
[root@localhost awk]# awk -F ':' '{if($1=="root"){print $0}}' test.txt
root:x:0:0:root:/root:/bin/bash