二、awk简单语法
2.1 函数sub gsub
替换功能
格式:sub(r, s ,目标) gsub(r, s ,目标)
[root@creditease awk]# cat sub.txt ABC DEF AHI GKL$123BAC DEF AHI GKL$213CBA DEF GHI GKL$321[root@creditease awk]# awk '{sub(/A/,"a");print $0}' sub.txt aBC DEF AHI GKL$123BaC DEF AHI GKL$213CBa DEF GHI GKL$321[root@creditease awk]# awk '{gsub(/A/,"a");print $0}' sub.txt aBC DEF aHI GKL$123BaC DEF aHI GKL$213CBa DEF GHI GKL$321注:sub只会替换行内匹配的第一次内容;相当于sed ‘s###’ gsub 会替换行内匹配的所有内容;相当于sed ‘s###g’[root@creditease awk]# awk '{sub(/A/,"a",$1);print $0}' sub.txt aBC DEF AHI GKL$123BaC DEF AHI GKL$213CBa DEF GHI GKL$321练习:
0001|20081223efskjfdj|EREADFASDLKJCV0002|20081208djfksdaa|JDKFJALSDJFsddf0003|20081208efskjfdj|EREADFASDLKJCV0004|20081211djfksdaa1234|JDKFJALSDJFsddf以'|'为分隔, 现要将第二个域字母前的数字去掉,其他地方都不变, 输出为:0001|efskjfdj|EREADFASDLKJCV0002|djfksdaa|JDKFJALSDJFsddf0003|efskjfdj|EREADFASDLKJCV0004|djfksdaa1234|JDKFJALSDJFsddf方法:awk -F '|' 'BEGIN{OFS="|"}{sub(/[0-9]+/,"",$2);print $0}' sub_hm.txtawk -F '|' -v OFS="|" '{sub(/[0-9]+/,"",$2);print $0}' sub_hm.txt2.2 if和slse的用法
内容:
AA
BC
AA
CB
CC
AA
结果:
AA YES
BC NO YES
AA YES
CB NO YES
CC NO YES
AA YES
1) [root@creditease awk]# awk '{if($0~/AA/){print $0" YES"}else{print $0" NO YES"}}' ifelse.txt AA YESBC NO YESAA YESCB NO YESCC NO YESAA YES解析:使用if和else,if $0匹配到AA,则打印$0 "YES",else反之打印$0 " NO YES" 。2)[root@creditease awk]# awk '$0~/AA/{print $0" YES"}$0!~/AA/{print $0" NO YES"}' ifelse.txt AA YESBC NO YESAA YESCB NO YESCC NO YESAA YES解析:使用正则匹配,当$0匹配AA时,打印出YES,反之,打印出“NO YES”2.3 next用法
如上题,用next来实现
next :跳过它后边的所有代码
[root@creditease awk]# awk '$0~/AA/{print $0" YES";next}{print $0" NO YES"}' ifelse.txt AA YESBC NO YESAA YESCB NO YESCC NO YESAA YES解析:{print $0" NO YES"}:此动作是默认执行的,当前边的$0~/AA/匹配,就会执行{print $0" YES";next}因为action中有next,所以会跳过后边的action 。如果符合$0~/AA/则打印YES ,遇到next后,后边的动作不执行;如果不符合$0~/AA/,会执行next后边的动作;next前边的(模式匹配),后边的就不执行,前边的不执行(模式不匹配),后边的就执行 。2.4 printf不换行输出以及next用法
printf :打印后不换行
如下文本,如果 Description:之后为空,将其后一行内容并入此行 。
Packages: Hello-1Owner: me me me meOther: who care?Description:Hello world!Other2: don't care想要结果:Packages: Hello-1Owner: me me me meOther: who care?Description: Hello world!Origial-Owner: me me me meOther2: don't care1)[root@creditease awk]# awk '/^Desc.*:$/{printf $0}!/Desc.*:$/{print $0}' printf.txt Packages: Hello-1Owner: me me me meOther: who care?Description:Hello world!Other2: don't care解析:使用正则匹配,匹配到'/^Desc.*:$/,就使用printf打印(不换行),不匹配的打印出整行 。2)使用if和else实现[root@creditease awk]# awk '{if(/Des.*:$/){printf $0}else{print $0}}' printf.txt Packages: Hello-1Owner: me me me meOther: who care?Description:Hello world!Other2: don't care3)使用next实现[root@creditease awk]# awk '/Desc.*:$/{printf $0;next}{print $0}' printf.txt Packages: Hello-1Owner: me me me meOther: who care?Description:Hello world!Other2: don't care注:可简写成awk '/Desc.*:$/{printf $0;next}1'printf.txt ## 1是pattern(模式),默认action(动作)是{print $0}2.5 去重后计数按要求重定向到指定文件
文本如下,要求计算出每项重复的个数,然后把重复次数大于2的放入gt2.txt文件中,把重复次数小于等于2的放入le2.txt文件中
[root@creditease files]# cat qcjs.txt aaabbbcccaaadddbbbrrrtttccceeedddrrrbbbrrrbbb[root@creditease awk]# awk '{a[$1]++}END{for(i in a){if(a[i]>2){print i,a[i]>"gt2.txt"}else{print i,a[i]>"le2.txt"}}}' qcjs.txt [root@creditease awk]# cat gt2.txt rrr 3bbb 4[root@creditease awk]# cat le2.txt aaa 2ccc 2eee 1ttt 1ddd 2解析:{print },或括号中打印后可直接重定向到一个新文件,文件名用双引号引起来 。如: {print $1 >"xin.txt"}三、awk需注意事项
a)NR==FNR ##不能写成NR=FNR(=在awk中是赋值的意思)
b)NR!=FNR ##NR不等于FNR
c){a=1;a[NR]} 这样会报错:同一条命令中变量和数组名不能重复 d)printf 输出的时候不换行
推荐阅读
- 算法一看就懂之「 堆栈 」
- Android视频技术探索之旅:美团外卖商家端的实践
- 孕妇瑜伽要注意什么?
- 哪些茶称之为绿茶?
- 汽车之家|技术工程师的金三银四,没有消失
- 跑步之前吃什么好
- 武夷岩茶的闻香之法
- 茶之雅趣投茶介绍
- 国医大师何任的茶疗养生之道
- 新疆安集海大峡谷 被称为无人之境场面震撼