基于单个字段的Bash排序,并基于另一个字段进行比较

时间:2015-05-14 21:50:38

标签: bash awk duplicates

我有一个制表符分隔的文件,其中包含一些重复的行。我有兴趣在第二个字段(位置)中查找具有重复项的行,然后仅保留第三个字段(质量)中具有最高值的行。 例如,如果文件如下所示:

chrom 1677 800
chrom 1677 850
chrom 1777 900
chrom 1799 900

我有兴趣为每个代表最高质量的职位保留一行:

chrom 1677 850
chrom 1777 900
chrom 1799 900

我可以找到重复的位置: awk'见过[$ 2] ++' file.txt的

但我不确定如何根据第三个字段中的值比较第二个字段中的重复行。任何帮助将不胜感激!

谢谢!

2 个答案:

答案 0 :(得分:1)

mydir$ echo $'chrom\t1677\t800\nchrom\t1677\t850\nchrom\t1779\t900\nchrom\t1777\t900' > tmp.txt
mydir$ cat tmp.txt
chrom   1677    800
chrom   1677    850
chrom   1779    900
chrom   1777    900
mydir$ sort -t$'\t' -k2,2 -k3,3nr tmp.txt | awk -v FS='\t' 'val!=$2 {val=$2;print}'
chrom   1677    850
chrom   1777    900
chrom   1779    900

答案 1 :(得分:1)

假设:

$ echo "$e"
chrom 1677 800
chrom 1677 850
chrom 1777 900
chrom 1799 900

你可以这样做:

$ echo "$e" | awk '{if (m[$2]<$3) {m[$2]=$3; seen[$2]=$0}} 
                    END {for (e in seen) print seen[e]}'
chrom 1677 850
chrom 1777 900
chrom 1799 900

如果您的文件是以制表符分隔的,而且实际上是一个文件:

awk -F $'\t' '{if (m[$2]<$3) {m[$2]=$3; seen[$2]=$0}} 
              END {for (e in seen) print seen[e]}' file