分享个awk 有点难度的用法(晕)

回复 收藏
本帖最后由 Landon 于 2016-6-11 16:43 编辑

awk的用法很多,很多高级的方法没看懂!
这里介绍2种时不时会用到

1 .  awk 去从   awk '!a[$2]++' gatfile.sh >> phy.txt
[root@adong ~]# cat gatfile.sh
gatfile "111.22.38.109" "99101" "cross" "22" "cross" "1.0.1.3_20160526_1" "127.0.0.1" "127.0.0.1" ""
gatfile "52.76.61.199" "99102" "cross" "22" "cross" "1.0.0.5_20160326_1" "127.0.0.1" "127.0.0.1" ""
gatfile "111.22.39.80" "99103" "cross" "22" "cross" "1.0.1.3_20160526_1" "127.0.0.1" "127.0.0.1" ""
gatfile "111.22.39.80" "99103" "cross" "22" "cross" "1.0.1.3_20160526_1" "127.0.0.1" "127.0.0.1" ""
gatfile "111.22.38.109" "99101" "cross" "22" "cross" "1.0.1.3_20160526_1" "127.0.0.1" "127.0.0.1" ""
[root@adong ~]#   awk '!a[$2]++' gatfile.sh >> phy.txt
[root@adong ~]# cat phy.txt
gatfile "111.22.38.109" "99101" "cross" "22" "cross" "1.0.1.3_20160526_1" "127.0.0.1" "127.0.0.1" ""
gatfile "52.76.61.199" "99102" "cross" "22" "cross" "1.0.0.5_20160326_1" "127.0.0.1" "127.0.0.1" ""
gatfile "111.22.39.80" "99103" "cross" "22" "cross" "1.0.1.3_20160526_1" "127.0.0.1" "127.0.0.1" ""
[root@adong ~]#

说明一下: 应该很容易看出,这是以$2 为准去从,以a[$2]作为下标,‘a[$2]++’ 获取a[$2]是重复的打印出来,然后 “ ! ”取反 ,追加到phy.txt


2.  awk 'NR==FNR{a[$0]}NR>FNR{if($0 in a) delete a[$0]}END{for(b in a)print b}' all_ser.txt in_ser.txt > ./out_ser.txt
这种应该是很多人都比较难理解的, 先看作用:

[root@adong ~]# cat all_ser.txt
abc_1
abc_2
abc_3
a_1
a_2
b_1
[root@adong ~]# cat in_ser.txt
abc_1
abc_2
abc_3
[root@adong ~]# awk 'NR==FNR{a[$0]}NR>FNR{if($0 in a) delete a[$0]}END{for(b in a)print b}' all_ser.txt in_ser.txt >out_ser.txt
[root@adong ~]# cat out_ser.txt
a_1
b_1
a_2

说明一下:
先介绍几个少见的参数
NR 是表示行数,它是一个相对行数,就是你awk 1个文件时候就显示1个文件的行数,awk 2个文件的时候就是显示2个文件的行数!
FNR 是表示绝对行数,它只会显示一个文件的行数!
delete 是删除和字面一样,应该算是awk 功能,还有next之类的,可以google下

作用:就是比对2个文件,in_ser.txt 和 all_ser.txt  都共同有的去掉,留下all_ser.txt 有的!(至于有什么用呢?以后就知道)

第一次NR==FNR{a[$0]} ,就是读all_ser.txt,a[$0]以$0为一个下标形成一个数组(当作标识既可,相同行表示就肯定是一样的)
第二次NR>FNR
{if($0 in a) delete a[$0]} , 为什么是大于呢?因为此时已经读进来 第二个文件,2个文件的相对行数肯定比第二个文件的绝对行数大,所以以此表示第二个文件;有一个条件 如果第二个文件的行在第一个文件里面也是存在的,就删除第一个文件的对应行!
END 这个大家应该都看过,就是整个计算或者比较过程结束,
这样下来就会剩下a_1 a_2 b_1;不加END就把过程也打印出来了!
剩下的我们会使用一个字母空间循环去接剩下来的,所以
{for(b in a)print b}  放置到out_ser.txt!

之前自己在铭哥这里看到这个awk 也是挺晕的,就没深究所以然,而因为这次在工作上也运用到了,所以决定把它搞懂,顺便分享给大家,相信会有和之前的我一样对这个特别晕的!所以我才把整个过程详细的说一次!

最后在搞个取交集的
[root@adong ~]# cat a.txt
12345678
8765432
asdfgh
[root@adong ~]# cat b.txt
12345678
kasdlasdlad
kasjdlasjda
lkajdlad
[root@adong ~]# cat a.txt  b.txt |sort|uniq -d
12345678


2016-06-10 10:49 举报
已邀请:
0

can1

赞同来自:

第二次NR>FNR{if($0 in a) delete a[$0]} 这里是if?还是for?

回复帖子,请先登录注册

退出全屏模式 全屏模式 回复
评分
可选评分理由: