文件去重:awk的高级用法
日常瞎掰
为什么别人都那么油菜花呢?
同样的事有才的人就能描写的既生动又形象,比如下面这段话:
“生活的琐碎,吐出来太矫情,咽下去又辣嗓子;百般无奈却涌上心头,话到嘴边又觉得不值一提...”
看看,别人一两句话就把一个普通人被生活琐事所困的境遇描绘的淋漓尽致。这要换成我也就是一句话的事:“卧槽,生活真TM累~~~”😅😅😅
真的是没有对比就没有伤害,这么一对比瞬间就觉得咱好像书读的太少,描述就显得太过简单粗暴了,虽然话糙理不糙,但不免有时难于拿上台面。
那是不是这样简单粗暴的方式就完全不可取呢?
当然不是了,有时候简单粗暴的方式更有利于解决问题,既节省时间又方便快捷。
根据多列去重
文件去重在处理数据时也是经常遇到的操作,所以Linux系统也配备了一个专门去重的命令uniq,可方便用来对文件进行去重操作,但这个命令只能对行内容完全相同的情况去重。
如果文件有多列,我们只想根据某些列进行去重,那么uniq命令就显得爱莫能助了。当然了,对于这样的去重功能随便用其他的程序语言比如R都可以轻松完成。
不过,有没有更简单的方式呢?这个时候我们就不得不提Linux命令中三驾马车之一——awk。这个命令用好了,可以帮助我们快速解决不少问题,之前写过关于该命令三个使用场景的帖子——《Linux: 数据处理三剑客之awk》,不懂得可以去看一看。今天我就来说一说另外一个使用场景,awk如何用来对文件去重。
例如我们有一个多列的文件,需要根据某几个对文件去重,例如:
chrII 167925 168425 . YBL027W_id001 +
chrII 167925 168425 . YBL027W_id005 +
chrII 332376 332876 . YBR048W_id001 +
chrII 332376 332876 . YBR048W_id005 +
chrII 415259 415759 . YBR084C-A_id001 -
chrII 415259 415759 . YBR084C-A_id004 -
chrII 426873 427373 . YBR090C_mRNA -
chrII 478846 479346 . YBR119W_id003 +
chrII 592768 593268 . YBR181C_id001 -
chrII 605781 606281 . YBR191W_id002 +
chrII 680039 680539 . YBR230C_id001 -
chrIII 178213 178713 . YCR031C_id002 -
上面的文件的格式一看就知道是bed,对于上面的文件,如果我们想根据位置信息去重,即根据文件前三列去重,该怎么怎么办呢?废话不多说,直接展示代码:
cat test.bed | awk '!a[$1,$2,$3]++'
结果如下
chrII 167925 168425 . YBL027W_id001 +
chrII 332376 332876 . YBR048W_id001 +
chrII 415259 415759 . YBR084C-A_id001 -
chrII 426873 427373 . YBR090C_mRNA -
chrII 478846 479346 . YBR119W_id003 +
chrII 592768 593268 . YBR181C_id001 -
chrII 605781 606281 . YBR191W_id002 +
chrII 680039 680539 . YBR230C_id001 -
chrIII 178213 178713 . YCR031C_id002 -
可以看出用awk命令去重相当的简单,只一行命令就可以到达效果,去除了前三列相同的行,保留了重复行中第一条记录,如果想只保留剩下重复的行,只需对命令稍作修改,如下:
cat test.bed | awk 'a[$1,$2,$3]++'
得到结果如下:
chrII 167925 168425 . YBL027W_id005 +
chrII 332376 332876 . YBR048W_id005 +
chrII 415259 415759 . YBR084C-A_id004 -
从结果不难看出,这一命令保留了上面去重命令去除的重复行,很简单的命令就可以得到上面去重命令的反向操作结果。
结束语
awk做为Linux三剑客之一,我觉得这个命令功能最为强大,这个命令用好了,可以为我们的数据处理带来很多便捷之处,简化操作步骤省去不少麻烦。这么好用的命令,你确定不试一试么?