正则三剑客(三)
三、awk工具的使用
1、截取文档中的某个段
# head -n2 test.txt |awk -F ':' '{print $1}' //test.txt是复制/etc/passwd内容 root bin
-F是用来指定分隔符,如果不加,则以空格过tab为分隔符,print为打印,$1为第一个字段,$2为第二个字段,以此类推,但$0表示整行,示例如下:
# head -n2 test.txt |awk -F ':' '{print $0}' root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin
print还可打印自定义的内容,但是自定义的内容要用双引号括起来,示例如下:
# head -n2 test.txt |awk -F ':' '{print $1"#"$2"%"}' root#x% bin#x%
2、匹配字符或者字符串
# awk '/oo/' test.txt root:x:0:0:root:/root:/bin/bash lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin # awk -F ':' '$1 ~/oo/' test.txt root:x:0:0:root:/root:/bin/bash
它可以让某个段去匹配,~是匹配的意思,awk还可以多次匹配,示例如下:
# awk -F ':' '/root/ {print $1,$3} /test/ {print $1,$3}' test.txt root 0 operator 11
这条命令表示在test.txt文件中打印root所在行用分隔符分开的第一部分和第三部分,awk匹配完root,再匹配test,它还可以只打印所匹配的段。
3、条件操作符
# awk -F ':' '$3=="0"' test.txt root:x:0:0:root:/root:/bin/bash
awk中可以用逻辑符号进行判断,比如==就是等于,另外还有>、>=、<、<=、!=等。当数字被双引号包起来,awk不会认为是数字,而会认为是字符,这里的意思就是匹配第三段是0的一行。
匹配第3段是5的一行,示例如下:
# awk -F ':' '$3=="5"' test.txt sync:x:5:0:sync:/sbin:/bin/sync
把uid大于500的行打印出来,示例如下:
# awk -F ':' '$3>=500' test.txt systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin systemd-network:x:998:996:systemd Network Management:/:/sbin/nologin polkitd:x:997:995:User for polkitd:/:/sbin/nologin
!=表示不匹配,可以针对某一个段的字符进行逻辑比较,示例如下:
# awk -F ':' '$7!="/sbin/nologin"' test.txt root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt
它还可以在两个段之间进行逻辑比较,示例如下:
# awk -F ':' '$3<$4' test.txt adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin mail:x:8:12:mail:/var/spool/mail:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin # awk -F ':' '$3>$4' test.txt sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt operator:x:11:0:operator:/root:/sbin/nologin systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin systemd-network:x:998:996:systemd Network Management:/:/sbin/nologin polkitd:x:997:995:User for polkitd:/:/sbin/nologin
还可以使用&&和||,它们分别表示“并且”和“或者”,示例如下:
# awk -F ':' '$3>"5" && $3<"7"' test.txt shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null # awk -F ':' '$3>1000 || $7=="/bin/bash"' test.txt root:x:0:0:root:/root:/bin/bash
4、awk的内置变量
awk常用的变量有OFS、NF、和NR,OFS和-F都是用来定义分隔符的,区别是OFS在输出的时候定义,NF表示用分隔符后一共有多少段,NR表示行号,示例如下:
# head -5 test.txt |awk -F ':' '{OFS="#"} {print $1,$3,$4}' # awk -F ':' '{OFS="#"} {if ($3>900) {print $1,$2,$3,$4}}' test.txt systemd-bus-proxy#x#999#997 systemd-network#x#998#996 polkitd#x#997#995 //打印第三段大于900的行的第1,2,3,4段
NF具体用法如下:
# head -n3 test.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin # head -n3 test.txt |awk -F 'x' '{print NF}' 2 2 2 //以x为分隔符一共分为两段,x左边为一段,x右边为一段 # head -n3 test.txt |awk -F ':' '{print NF}' 7 7 7 # head -n3 test.txt |awk -F ':' '{print $NF}' /bin/bash /sbin/nologin /sbin/nologin //这里NF表示有多少段,$NF表示最后一段的值
NR的用法,示例如下:
# head -n3 test.txt |awk '{print NR }' 1 2 3
NR也可做为判断条件,示例如下:
# wc -l test.txt 21 test.txt # awk 'NR>20' test.txt sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin # awk 'NR>19' test.txt postfix:x:89:89::/var/spool/postfix:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
NR也可以配合段匹配一起使用,示例如下:
# awk -F ':' 'NR<20 && $1 ~ /roo/' test.txt root:x:0:0:root:/root:/bin/bash
5、awk中的数学运算
awk可以更改段值,示例如下:
# head -n3 test.txt |awk -F ':' '$1="root"' root x 0 0 root /root /bin/bash root x 1 1 bin /bin /sbin/nologin root x 2 2 daemon /sbin /sbin/nologin //这条命令意思是把打印出来的内容的第一段都改成root
awk也可以对各个段的值进行数学运算,示例如下:
# head -n2 test.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin # head -n2 test.txt |awk -F ':' '{$7=$3+$4; print $0}' root x 0 0 root /root 0 bin x 1 1 bin /bin 2
awk可以计算某个段的总和,示例如下:
# awk -F ':' '{(tot=tot+$3)}; END {print tot}' test.txt 3639
该命令表示把文件里所有第三段的和加在一起,END是awk特有的语法,表示所有的行都已经执行。
# awk -F ':' '{if ($1=="root") {print $0}}' test.txt root:x:0:0:root:/root:/bin/bash # awk -F ':' '{if ($3=="5") {print $0}}' test.txt sync:x:5:0:sync:/sbin:/bin/sync
到这里正则三剑客我们就学完了,其中awk工具功能最多需要多练,后面我会发出关于awk的练习题,帮助大家更加熟悉的掌握awk工具的使用。