【问题标题】:awk/bash remove lines with an unique id and keep the lines that has the max/min value in a column under the same IDawk/bash 删除具有唯一 ID 的行,并将具有最大/最小值的行保留在同一 ID 下的列中
【发布时间】:2014-07-03 01:11:24
【问题描述】:

如果我们有以下输入,并且想首先检测文件中的 cpd_number ($2) 是否唯一,则删除整行。在这种情况下,应删除带有“cpd-6666666”的行。
其次,如果有多行保存在相同的“cpd_number”下,则只打印出具有最大和最小“log_ratio”($17)的两行。

targetID,cpd_number,Cell_assay_id,Cell_alt_assay_id,Cell_type_desc,Cell_Operator,Cell_result_value,Cell_unit_value,assay_id,alt_assay_id,type_desc,operator,result_value,unit_value,Ratio_operator,Ratio,log_ratio,Cell_experiment_date,experiment_date,Cell_discipline,discipline
49,cpd-7788990,1212,2323, IC50 ,,100,uM,1334,1331,Ki,,10,uM,,10,-1,12/6/2006 0:00,2/16/2007 0:00,Cell,Enzyme
49,cpd-7788990,5555,6666, IC50 ,>,150,uM,1334,1331,Ki,,10,uM,>,15,-1.176091259,12/6/2006 0:00,2/16/2007 0:00,Cell,Enzyme
49,cpd-7788990,8888,9999, IC50 ,,200,uM,1334,1331,Ki,,10,uM,,20,-1.301029996,12/6/2006 0:00,2/16/2007 0:00,Cell,Enzyme
49,cpd-6666666,8888,9999, IC50 ,,400,uM,1334,1331,Ki,,10,uM,,40,-1.602059991,12/6/2006 0:00,2/16/2007 0:00,Cell,Enzyme

理想的输出应该是

targetID,cpd_number,Cell_assay_id,Cell_alt_assay_id,Cell_type_desc,Cell_Operator,Cell_result_value,Cell_unit_value,assay_id,alt_assay_id,type_desc,operator,result_value,unit_value,Ratio_operator,Ratio,log_ratio,Cell_experiment_date,experiment_date,Cell_discipline,discipline
49,cpd-7788990,1212,2323, IC50 ,,100,uM,1334,1331,Ki,,10,uM,,10,-1,12/6/2006 0:00,2/16/2007 0:00,Cell,Enzyme
49,cpd-7788990,8888,9999, IC50 ,,200,uM,1334,1331,Ki,,10,uM,,20,-1.301029996,12/6/2006 0:00,2/16/2007 0:00,Cell,Enzyme

我尝试使用 awk 计数功能,但它似乎不太好用。任何大师都可以给一些cmets吗?谢谢!

【问题讨论】:

  • 您还应该发布您制作的 awk 脚本。它也可以提供帮助。

标签: bash awk count max min


【解决方案1】:

虽然不如 perl 答案简洁,但这里有一个可执行的 awk 文件:

#!/usr/bin/awk -f

BEGIN { FS="," }

NR==1 {print; next}

{
  a[$2,$17]=$0

  h=high[$2]
  high[$2]=$17>h || h=="" ? $17 : h

  l=low[$2]
  low[$2]=$17<l || l=="" ? $17 : l
}

END {
  for(i in high) {
    if(low[i]!=high[i]) {
      print a[i,high[i]]
      print a[i,low[i]]
    }
  }
}

其中:

  • 打印标题行
  • ahighslows 中为每个键存储整行
  • END 中,遍历high 数组并通过从a 检索它们来打印highlow 不同的行

【讨论】:

  • 也是优雅的解决方案。你能解释一下这条线吗? "high[$2]=$17>h || h=="" ? $17 : h" & "low[$2]=$17
  • 当然。 h 已分配给 high[$2]。未分配数组的默认查找是“”,因此 h 将是“”或先前分配的值。 high[] 行使用ternary operator,其中条件是$17&gt;h(大于)或h=="" 为真之间的或(||)。如果任一为真,则将$17 分配给high[$2]。如果不是,请将h 重新分配回high[$2]low[] 代码类似,但在条件中测试 $17&lt;l(小于)。
  • 感谢您解释晦涩难懂的 awk 行。我可以知道你在哪里学习了所有这些更高级的 awk 吗?边做边学还是有推荐的书?不过,我读过的所有 awk 教程都更像是中级。
  • 为了阅读,我建议“AWK 编程语言”,虽然我很久以前买的,它很便宜。我在这里看到其他人建议“有效的 awk 编程”,尽管我从未见过副本。主要是通过做。您可以通过挑选问题并尝试在“家庭游戏版本”中自己解决问题来将此站点视为教程(无需先阅读其他答案或发布答案,直到您觉得这样做为止)。寻找具有明确输入/输出的问题。祝你好运!
  • @Chubaka 不幸的是,随着 perl 和 python 等高级脚本语言的日益普及,awk 的数量稳步下降。没有任何新书,所以最好的办法是学习免费提供的 GNU awk 用户手册。由于可移植性,人们通常求助于 awk。在这个网站上学习 awk 问题和答案也会有所帮助
【解决方案2】:

如果你可以尝试perl会更容易:

perl -MList::Util=max,min -F, -lane '
    print if $.==1;
    $line{$F[1]}{$F[16]}=$_; 
    $count{$F[1]}++ 
}{
    for $key (keys %count) {
        next if $count{$key}==1; 
        print $line{$key}{ max keys %{$line{$key}} };
        print $line{$key}{ min keys %{$line{$key}} }
     }
' file

输出:

targetID,cpd_number,Cell_assay_id,Cell_alt_assay_id,Cell_type_desc,Cell_Operator,Cell_result_value,Cell_unit_value,assay_id,alt_assay_id,type_desc,operator,result_value,unit_value,Ratio_operator,Ratio,log_ratio,Cell_experiment_date,experiment_date,Cell_discipline,discipline
49,cpd-7788990,1212,2323, IC50 ,,100,uM,1334,1331,Ki,,10,uM,,10,-1,12/6/2006 0:00,2/16/2007 0:00,Cell,Enzyme
49,cpd-7788990,8888,9999, IC50 ,,200,uM,1334,1331,Ki,,10,uM,,20,-1.301029996,12/6/2006 0:00,2/16/2007 0:00,Cell,Enzyme

说明:

  • 使用核心模块(随每个perl 二进制文件提供)查找$17 的最小值和最大值。
  • 使用-F 拆分, 上的行。
  • -a 选项将分隔符上的行拆分为 @F 数组。
  • 如果它是我们的第一行,我们打印它
  • 我们创建一个散列哈希,第二列作为键,第 17 列作为第二层键。值为整行
  • 我们创建一个计数器哈希来保持第二列的计数
  • END 块中,我们从计数器哈希中遍历我们的密钥。如果计数为 1,我们将跳过它。
  • 如果计数器大于 1,我们将打印第 17 列的最小值和最大值。

【讨论】:

  • 这个 perl 解决方案看起来非常优雅。由于我对 perl 的了解为零,因此我需要学习一下才能详细阅读此脚本。
猜你喜欢
  • 2014-03-29
  • 2019-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-09
  • 1970-01-01
  • 2018-12-29
相关资源
最近更新 更多