二十八awk
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二十八awk相关的知识,希望对你有一定的参考价值。
二十八、awkawk:流式编辑器,针对文档的行进行操作。awk兼具sed的所有功能,且更强大。可以对每段做匹配,不能更改文件内容,不像sed有-i选项能更改内容。
截取文档中的某段,示例:
-F:指定分隔符,若不加-F,则以空格或tab为分隔符。print为打印的动作,用来打印某个字段。$1为第一个字段,以此类推,$0表示整行。
# awk -F ':' {print $1} test.txt 打印第一段
# head -n2 test.txt |awk -F ':' '{print $1}' 打印前两行的第一段
# head -n2 test.txt |awk -F ':' '{print $0}' 打印前两行整行(所有段)
# awk -F ':' '{print $1,$2,$4}' test.txt 多打印几段,用逗号隔开;也可用#,但是#麻烦一点,要用双引号括起来,示例:
# awk -F ':' '{print $1"#"$2"#"$4}' test.txt
root#x#0
bin#x#1
daemon#x#2
# awk -F ':' '{print $0}' test.txt 打印所有行
不指定分隔符,示例:
# awk '{print $1}' 1.txt
1
aa
cc
# cat 1.txt
1 2
aa bb
cc d
匹配字符或字符串
# awk '/ot/' test.txt 指定字符为ot
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologi
# awk -F ':' '$1 ~/oo/' test.txt
root:x:0:0:root:/root:/bin/bash
精确匹配,第一段里包含oo的行,1后加个~。~为匹配的意思。这就是比grep和sed更强大的地方,对段匹配。同样也支持正则,如o+,o*等等。所有符号都不用加脱义字符,这是awk比grep和sed方便的地方。
# awk -F ':' '/root/ {print $1,$2} /user/ {print $1,$2}' test.txt 多次匹配
先匹配root,再匹配user。
条件操作符
逻辑符号判断,==为等于,还有>、>=、<、<=、!=等,!=为不匹配。若把比较的数字用双引号括起来,awk会认为是字符,不括起来会认为是数字。
# awk -F ':' '$3=="0"' test.txt
# awk -F ':' '$3>="0"' test.txt
# awk -F ':' '$3>=500' test.txt
匹配数字时就不要加双引号,否则认为是字符
# awk -F ':' '$7!="/sbin/nologin"' test.txt 是字符串,所以要加上双引号
# awk -F ':' '$3<$4' test.txt 两个段之间进行逻辑比较,第三段小于第四段
||和&&,分别表示“或者”,“并且”。示例:
# awk -F ':' '$3<"4" && $3<"7"' test.txt
此处4和7代表字符,所以要用双引号括起来。
# awk -F ':' '$3>1000 || $7=="/bin/bash"' test.txt
第三段大于1000,或者第七段等于/bin/bash的。
# awk -F ':' '$3>1000 || $7 ~ /bash/' test.txt
匹配第七段为bash的,或者第三段大于1000的。
awk的内置变量
awk常用变量:OFS、NF和NR。
OFS:和-F选项有类似的功能,也是用来定义分隔符的,但是它是在输出的时候定义。
NF:表示用分隔符分隔后一共有多少段
NR:表示行号
OFS用法示例:
# head -n5 test.txt |awk -F ':' '{OFS="#"} {print $1,$3}'
定义分隔符为#,也可以定义为@
root#0
bin#1
daemon#2
adm#3
lp#4
更高级的用法,示例:
# awk -F ':' '{OFS="#"} {if ($3<1000) {print $1,$3,$4}}' /etc/passwd
if:如果,判断的作用。如果$3<1000 则打印出 $1$3$4 ,输出并以#分隔显示。
NF用法示例:
# awk -F ':' '{print NF":" $0}' test.txt 显示所有段有多少段。
# awk -F ':' 'NF==7 && $1 ~ /root|sync/' test.txt 配合匹配一起用
# head -n3 /etc/passwd |awk -F ':' '{print NF}'
7
7
7
# head -n3 /etc/passwd |awk -F ':' '{print $NF}'
/bin/bash
/sbin/nologin
/sbin/nologin
此处NF是多少段,$NF是最后一段的值。
NF:表示用分隔符分隔后一共有多少段
NR用法示例:
# awk -F ':' '{print NR":" $0}' test.txt 显示所有段的行号
# head -n3 /etc/passwd |awk -F ':' '{print NR}'
1
2
3
# awk -F ':' 'NR<=10' test.txt 前十行,NR可作为判断条件。
NR也可配合段匹配一起使用,示例:
# awk -F ':' 'NR<=10 && $1 ~ /root|sync/' test.txt
NR:表示行号
# awk -F ':' '{print $NR":"$NF}' test.txt 显示出的内容将从$1开始往后推。
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
# 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:2:2:daemon:/sbin:/sbin/nologin
此处是一个等于号,是赋值的意思,两个等于号就是匹配出来的意思,要分清楚。可以看到前三行的第一段都变为了root。可以直接定义分隔符为“:”。
计算某个段的总和,示例:
# awk -F ':' '{(tot=tot+$3)}; END {print tot}' test.txt
4610
(表示每一行的第三段相加,最后再print求和)
END:awk特有语法,表示所有的行都执行。
if:判断。
for:循环。
# awk -F ':' '{if ($1=="root") {print $0}}' test.txt
root:x:0:0:root:/root:/bin/bash
先判断第一段有root的,再打印整行。
以上是关于二十八awk的主要内容,如果未能解决你的问题,请参考以下文章