如何删除重复项并仅打印包含字符串且在特定列中具有最高值的行

如何删除重复项并仅打印包含字符串且在特定列中具有最高值的行

例如下面的例子

我想从第二列中删除重复的 ID,并仅打印第三列中值最高的 ID

MS1199089 PT01000001.1.1 0.63 16.4 0.7 -   
MS0068379 PT01000007.1.1 0.96 13.9 0.4 core  
MS0950857 PT01000010.1.8 0.1 17.5 0.2 S11  
MS0736357 PT01000010.1.8 0.062 18.2 0.5 (Saprolegnia  
MS0260587 PT01000010.1.2 0.5 15.4 0.1 VII-activating  
MS0402367 PT01000010.1.2 0.6 15.1 0.1 V-activating  
MS0416158 PT01000010.1.2 0.65 15 0.1 Callorhinchus  
MS0438713 PT01000010.1.3 0.2 18.1 0 TRP3  
MS0436466 PT01000010.1.3 0.48 17 0 -  
MS0436647 PT01000010.1.3 0.49 16.9 0 Stomatobaculum  
MS0438816 PT01000010.1.3 0.59 16.7 0 peptidase  
MS0436602 PT01000010.1.3 0.55 16.8 0 Desulfosporosinus  

输出应该是

MS1199089 PT01000001.1.1 0.63 16.4 0.7 -
MS0068379 PT01000007.1.1 0.96 13.9 0.4 core  
MS0950857 PT01000010.1.8 0.1 17.5 0.2 S11  
MS0416158 PT01000010.1.2 0.65 15 0.1 Callorhinchus  
MS0438816 PT01000010.1.3 0.59 16.7 0 peptidase  

答案1

一种避免排序的相当 KISS 方法是处理文件两次,第一次找到每个第二列键的最大值,第二次打印包含这些值的行:

$ awk 'NR==FNR{x[$2] = $3+0 > x[$2] ? $3 : x[$2]; next} $3 == x[$2] {print}' file file
MS1199089 PT01000001.1.1 0.63 16.4 0.7 -
MS0068379 PT01000007.1.1 0.96 13.9 0.4 core
MS0950857 PT01000010.1.8 0.1 17.5 0.2 S11
MS0416158 PT01000010.1.2 0.65 15 0.1 Callorhinchus
MS0438816 PT01000010.1.3 0.59 16.7 0 peptidase

就目前情况而言,这将打印出所有与每个最大值相关的实例 - 您可以添加!seen[$2]++条件将其限制为第一次出现。

答案2

我想这就是你要找的:

$ sort -gt' ' -k3,3r foo.txt | awk '!seen[$2]++' | sort -t' ' -k2
MS1199089 PT01000001.1.1 0.63 16.4 0.7 -   
MS0068379 PT01000007.1.1 0.96 13.9 0.4 core  
MS0416158 PT01000010.1.2 0.65 15 0.1 Callorhinchus  
MS0438816 PT01000010.1.3 0.59 16.7 0 peptidase  
MS0950857 PT01000010.1.8 0.1 17.5 0.2 S11

答案3

可以sort这样做:

sort -uk2,2 <(sort -k3,3rn FileName)

改变FileName以……的名义你的文件并从包含文件的同一目录中运行该命令。

输出:

MS1199089 PT01000001.1.1 0.63 16.4 0.7 -   
MS0068379 PT01000007.1.1 0.96 13.9 0.4 core  
MS0416158 PT01000010.1.2 0.65 15 0.1 Callorhinchus  
MS0438816 PT01000010.1.3 0.59 16.7 0 peptidase  
MS0950857 PT01000010.1.8 0.1 17.5 0.2 S11

保存原始订单但是,你可以grepsort这样使用:

grep "$(sort -k3,3rn FileName | sort -uk2,2)" FileName

改变两次发生FileName以……的名义你的文件并从包含文件的同一目录中运行该命令。

输出:

MS1199089 PT01000001.1.1 0.63 16.4 0.7 -
MS0068379 PT01000007.1.1 0.96 13.9 0.4 core
MS0950857 PT01000010.1.8 0.1 17.5 0.2 S11
MS0416158 PT01000010.1.2 0.65 15 0.1 Callorhinchus
MS0438816 PT01000010.1.3 0.59 16.7 0 peptidase

保存输出上述任一命令文件> SaveOutput.txt在它们后面添加如下内容:

sort -uk2,2 <(sort -k3,3rn FileName) > SaveOutput.txt

grep "$(sort -k3,3rn FileName | sort -uk2,2)" FileName > SaveOutput.txt

输出将保存到SaveOutput.txt同一目录中命名的文件中。

请参见man sortman grep了解更多信息。

还请看一下LC_ALL=C它的作用以及你可能需要它的原因。感谢@bac0n提出这个问题评论

相关内容