仅当字符串在特定列中不存在时才打印该行,同时考虑UNIX

时间:2017-11-15 17:53:39

标签: bash shell unix awk

所以,我有以下列表文件,包含千行:

NP_000007.1     ACADM   1457    rs1061337       not_match
NP_000007.1     ACADM   2761    rs2229249       not_match
NP_000007.1     ACADM   2761    rs2229249       not_match
NP_000019.2     AGL     1094    rs1042090       1398
NP_000019.2     AGL     1094    rs1042090       1395
NP_000057.1     C8B     1078    rs1013579       117
NP_000057.1     C8B     932     rs856847        345
NP_000057.1     C8B     932     rs856831        not_match
NP_000057.1     C8B     932     rs856841        429
NP_000076.2     CLCNKB  48      rs5251          334

如果在第五列中至少出现一次not_match模式,我想为第一列中分组的每组字符串删除这些行。因此,只打印第一列中由相同字符串分组的行,这些行仅对应于第五列中的数字。

所需的输出是:

NP_000019.2     AGL     1094    rs1042090       1398
NP_000019.2     AGL     1094    rs1042090       1395
NP_000076.2     CLCNKB  48      rs5251          334

我认为在一些步骤中用“not_match”模式和第五列中的数字分隔行,然后查看第一列中是否存在重合并散列这些巧合。但是我想在同一个文件中一步完成。我怎么能在Unix环境下得到它?提前致谢

2 个答案:

答案 0 :(得分:3)

awk救援!

两遍算法将是最简单的

$ awk 'NR==FNR {                       # in the first round 
         if($NF=="not_match") a[$1];   # record the keys to be deleted
         next}                         #
       !($1 in a)' file{,}             # in the second round skip them

请注意,file{,}file file

的简写
NP_000019.2     AGL     1094    rs1042090       1398
NP_000019.2     AGL     1094    rs1042090       1395
NP_000076.2     CLCNKB  48      rs5251          334

答案 1 :(得分:1)

替代 sort + awk 解决方案:

sort -k1,1 -k5,5r file | awk '!($1 in a){ a[$1]=$5 }a[$1]!="not_match"'

输出:

NP_000019.2     AGL     1094    rs1042090       1398
NP_000019.2     AGL     1094    rs1042090       1395
NP_000076.2     CLCNKB  48      rs5251          334