awk命令

grep:更适合单纯的查找或匹配文本


sed:更适合编辑文本


awk:更适合格式化文本,对文本进行较复杂格式处理。


awk

awk是行处理器: 相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息


awk处理过程:依次对每一行进行处理,然后输出


awk命令形式:awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file


[-F|-f|-v] 大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value


' ' 引用代码块


BEGIN 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符


// 匹配代码块,可以是字符串或正则表达式


{} 命令代码块,包含一条或多条命令


; 多条命令使用分号分隔


END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息


特殊要点:


$0 表示整个当前行


$1 每行第一个字段


NF 字段数量变量


NR 每行的记录号,多文件记录递增


FNR 与NR类似,不过多文件记录不递增,每个文件都从1开始


\t 制表符


\n 换行符


FS BEGIN时定义分隔符


RS 输入的记录分隔符, 默认为换行符(即文本是按一行一行输入)


~ 匹配,与==相比不是精确比较


!~ 不匹配,不精确比较


== 等于,必须全部相等,精确比较


!= 不等于,精确比较


&&  逻辑与


|| 逻辑或


+ 匹配时表示1个或1个以上


/[0-9][0-9]+/ 两个或两个以上数字


/[0-9][0-9]*/ 一个或一个以上数字


FILENAME 文件名


OFS 输出字段分隔符, 默认也是空格,可以改为制表符等


ORS 输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕


-F'[:#/]' 定义三个分隔符


print & $0


print 是awk打印指定内容的主要命令


awk '{print}' /etc/passwd == awk '{print $0}' /etc/passwd


awk '{print " "}' /etc/passwd //不输出passwd的内容,而是输出相同个数的空行,进一步解释了awk是一行一行处理文本


awk '{print "a"}' /etc/passwd //输出相同个数的a行,一行只有一个a字母


awk -F":" '{print $1}' /etc/passwd


awk -F: '{print $1; print $2}' /etc/passwd //将每一行的前二个字段,分行输出,进一步理解一行一行处理文本


awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd //输出字段1,3,6,以制表符作为分隔符


-f指定脚本文件


awk -f script.awk file


BEGIN{


FS=":"


}


{print $1} //效果与awk -F":" '{print $1}'相同,只是分隔符使用FS在代码自身中指定


awk 'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}' test


I find 4 blank lines.


ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}' //计算文件大小


total size is 17487


-F指定分隔符


$1 指指定分隔符后,第一个字段,$3第三个字段, \t是制表符


一个或多个连续的空格或制表符看做一个定界符,即多个空格看做一个空格


awk -F":" '{print $1}' /etc/passwd


awk -F":" '{print $1 $3}' /etc/passwd //$1与$3相连输出,不分隔


awk -F":" '{print $1,$3}' /etc/passwd //多了一个逗号,$1与$3使用空格分隔


awk -F":" '{print $1 " " $3}' /etc/passwd //$1与$3之间手动添加空格分隔


awk -F":" '{print "Username:" $1 "\t\t Uid:" $3 }' /etc/passwd //自定义输出


awk -F: '{print NF}' /etc/passwd //显示每行有多少字段


awk -F: '{print $NF}' /etc/passwd //将每行第NF个字段的值打印出来


awk -F: 'NF==4 {print }' /etc/passwd //显示只有4个字段的行


awk -F: 'NF>2{print $0}' /etc/passwd //显示每行字段数量大于2的行


awk '{print NR,$0}' /etc/passwd //输出每行的行号


awk -F: '{print NR,NF,$NF,"\t",$0}' /etc/passwd //依次打印行号,字段数,最后字段值,制表符,每行内容


awk -F: 'NR==5{print}' /etc/passwd //显示第5行


awk -F: 'NR==5 || NR==6{print}' /etc/passwd //显示第5行和第6行


route -n|awk 'NR!=1{print}' //不显示第一行


awk '{print $1,$2,$3}' Nym.RPKM.20160923.txt:打印出Nym文件的第1,2,3 列


awk '{print $1 "\t" $2 "\t" $3}' Nym.RPKM.20160923.txt:打印出整齐的三列,中间去掉逗号,需要加带双引号的制表符"\t"


条件表达式


== != > >=


awk -F":" '$1=="mysql"{print $3}' /etc/passwd


awk -F":" '{if($1=="mysql") print $3}' /etc/passwd //与上面相同


awk -F":" '$1!="mysql"{print $3}' /etc/passwd //不等于


awk -F":" '$3>1000{print $3}' /etc/passwd //大于


awk -F":" '$3>=100{print $3}' /etc/passwd //大于等于


awk -F":" '$3<1{print $3}' /etc/passwd //小于


awk -F":" '$3<=1{print $3}' /etc/passwd //小于等于


逻辑运算符


&& 逻辑与


|| 逻辑或


awk -F: '$1~/mail/ && $3>8 {print }' /etc/passwd //逻辑与,$1匹配mail,并且$3>8


awk -F: '{if($1~/mail/ && $3>8) print }' /etc/passwd


awk -F: '$1~/mail/ || $3>1000 {print }' /etc/passwd //逻辑或


awk -F: '{if($1~/mail/ || $3>1000) print }' /etc/passwd


数值运算


awk -F: '$3 > 100' /etc/passwd


awk -F: '$3 > 100 || $3 < 5' /etc/passwd


awk -F: '$3+$4 > 200' /etc/passwd


awk -F: '/mysql|mail/{print $3+10}' /etc/passwd //第三个字段加10打印


awk -F: '/mysql/{print $3-$4}' /etc/passwd //减法


awk -F: '/mysql/{print $3*$4}' /etc/passwd //求乘积


awk '/MemFree/{print $2/1024}' /proc/meminfo //除法


awk '/MemFree/{print int($2/1024)}' /proc/meminfo //取整


输出分隔符OFS


awk '$6 ~ /FIN/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt


awk '$6 ~ /WAIT/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt


//输出字段6匹配WAIT的行,其中输出每行行号,字段4,5,6,并使用制表符分割字段


输出处理结果到文件


①在命令代码块中直接输出 route -n|awk 'NR!=1{print > "./fs"}'


②使用重定向进行输出 route -n|awk 'NR!=1{print}' > ./fs


示例演示:

指定输出行或列


在awk中一行叫record,一列叫field。用NR和NF即可指定输出行或列。


NR:number of record 表示打印出行的数量


NF:number of field 表示打印出列的数量


1、输出第4行:awk 'NR==4{print NR,$0}' Nym.RPKM.20160923.txt


'NR==4{print NR,$0}'

2、输出第4列:awk '{print NF,$4}' Nym.RPKM.20160923.txt,去掉NF则不显示左边总列数。


awk '{print NF,$4}'

3、输出第4行第4列:


awk 'NR==4{print $4}' Nym.RPKM.20160923.txt,显示一个数字。


4、输出第4-8列,一步命令(暂时还没学会,后面更新):


awk 'NR==1{print $0}' Nym.RPKM.20160923.txt:先查看所有的列名,数。


awk '{print NR,$4,$5,$6,$7,$8}' OFS="\t" Nym.RPKM.20160923.txt,加OFS="\t"可使列显示很整齐。


'{print NR,$4,$5,$6,$7,$8}' OFS="\t"

5、输出第4列大于1的数并显示行号:


awk '$4>1{print NR,$1,$4}' OFS="\t" Nym.RPKM.20160923.tx


'$4>1{print NR,$1,$4}' OFS="\t"

6、输出第4列大于等于0.5小于1的行,并显示行号:


awk '$4>=0.5 && $4<=1{print NR, $1,$4}' OFS="\t" Nym.RPKM.20160923.txt,逻辑与


'$4>=0.5 && $4<=1{print NR, $1,$4}'

7、输出第4列小于等于0.5或大于等于1的行,并显示行号:


awk '$4<=0.5 || $4>=1{print NR, $1,$4}' OFS="\t" Nym.RPKM.20160923.txt,逻辑或


'$4<=0.5 || $4>=1{print NR, $1,$4}'

8、输出第3列大于1且第4列小于1的行,并显示行号:


awk '$3>1 && $4<1{print NR, $1,$3,$4}' OFS="\t" Nym.RPKM.20160923.txt,逻辑与


'$3>1 && $4<1{print NR, $1,$3,$4}'

9、输出第3列和第4列等于0的行:


awk '$3==0 && $4==0{print NR, $1,$3,$4}' OFS="\t" Nym.RPKM.20160923.txt,指定一个数,必须要用双等号==赋值


'$3==0 && $4==0{print NR, $1,$3,$4}'

10、打印出带有行号的第1到3列:awk '{print NR, $1 "\t" $2 "\t" $3}' Nym.RPKM.20160923.txt


NR,

11、打印出所有列数,显示在左边:awk '{print NF $0}' Nym.RPKM.20160923.txt


NF,

$0表示打印出所有,如果要空一格,用逗号隔开或用"\t":awk '{print NF, $0}' Nym.RPKM.20160923.txt或awk '{print NF "\t" $0}' Nym.RPKM.20160923.txt。(awk中的空格是认为要把左边和右边字符串拼接起来)。


12、打印出第一列字符串为Nym的所有列:awk '$1==“Nym.canu0775170”{print NR, $0}' Nym.RPKM.20160923.txt,字符串加双引号“”,否则会默认为数值型不显示出来。


'$1==“Nym.canu0775170”{print NR, $0}'

13、显示部分:awk '$1==“Nym.canu0775170”{print NR, $1,$3}' Nym.RPKM.20160923.txt


'$1==“Nym.canu0775170”{print NR, $1,$3}'

14、筛选有8列的行:awk 'NF==8{print NR,$0}' Nym.RPKM.20160923.txt


'NF==8{print NR,$0}'

15、输入分隔符:awk ‘BEGIN{FS=“,”}{print $1,$2}’


输出分隔符:awk ‘BEGIN{OFS=“,”}{print $1,$2}’


合并:awk ‘BEGIN{FS=“,”;OFS=“ \t ”}{print $1,$2}’,输出后会出现制表符。


awk

16、同时读取两个文件内容:awk ‘{print NR, FILENAME,$0}’ file1.txt file2.txt


展示出每一行有多少列:awk {print NF} file1.txt


筛选出每一行的最后一列:awk ‘{print $NF}’ file1.txt


筛选出每一行的倒数第二列:awk ‘{print $(NF-1)}’ file1.txt


awk计算

正则表达式// 结合awk

(1)筛选出含abc的内容:awk ‘/abc/{print $0}’ file1.txt ,直接指定并匹配


(2)筛选出含a和c的内容:awk ‘/a.c/{print $0}’ file1.txt 点表示匹配任意一个字母


(3)筛选出含a.c的内容:awk ‘/a\.c/{print $0}’ file1.txt 需要加一个转译字符\ 右斜杠


(4)筛选出含a/c的内容:


awk ‘/a\/c/{print $0}’ file1.txt 转译字符‘/a\/c/


a\c : awk ‘/a\\c/{print $0}’ file1.txt


a?c : awk ‘/a\?c/{print $0}’ file1.txt


(5)^开始 $结尾


/^abc/:匹配所有开头为abc 的字符


/abc$/:匹配所有结尾为abc 的字符 ,如awk ‘/abc$/’{print $0} file1.txt


/a[xyz]c/


/a[a-z]c/


/a[a-zA-Z]c/


(6)* +


/a*b/ :*跟在一个字母后面表示这个字母可以在匹配结果中出现0次或多次


/a+b/:+表这个字母至少要出现1次


(7)?


/a?b/:?表a可以有可以没有


(8){}


/ab{3}c/ :表b必须出现3次


/ab{3,4}c/ :表b可以出现3-4次


/ab{3,}c/ :表b的次数不限,但不能出现其他字母


(9)():把一串东西看成一个整体


/(ab)+c/ :把ab看成一个整体,同时出现,次数不限,最后c结尾

发布于 2021-03-29 13:17