【问题标题】:awk: test if the value in a column is less or more than others and make unionawk:测试列中的值是否小于或大于其他值并进行联合
【发布时间】:2013-09-21 05:30:47
【问题描述】:

我正在尝试使用 awk 命令来合并这两个数据集。我想获取 fileA.$1 和 fileB.$1 相同的所有行,并且 fileA.$4 和 fileA.$5 的平均值在 fileB.$2 和 fileB.$3 之间。 (fileA.$1=fileB.$1 AND fileB.$2

fileA                           
chr1    Mot TF  500 700 0.9893  target1 600
chr1    Mot TF  100 300 0.9893  target1 200
chr1    Mot TF  1000    2000    0.9893  target1 1500
chr2    Mot TF  500 700 0.9502  target2 600

fileB       
chr1    500 1000
chr1    400 800
chr1    100 800
chr3    100 500

desired result                              
chr1    500 1000    chr1    Mot TF  500 700 0.9893  target1 600
chr1    400 800 chr1    Mot TF  500 700 0.9893  target1 600
chr1    100 800 chr1    Mot TF  500 700 0.9893  target1 600
chr1    100 800 chr1    Mot TF  100 300 0.9893  target1 200

【问题讨论】:

    标签: awk compare union


    【解决方案1】:
    #!/usr/bin/awk -f
    
    BEGIN {
        FS = OFS = "\t"
    }
    NR == FNR {
        a0[NR] = $0
        a1[NR] = $1
        av[NR] = ($4 + $5) / 2
        next
    }
    {
        for (i = 1; i in a0; ++i) {
            if (a1[i] == $1 && av[i] > $2 && av[i] < $3) {
                print $0, a0[i]
            }
        }
    }
    

    运行:

    awk -f script.awk fileA fileB
    

    输出:

    chr1    500 1000    chr1    Mot TF  500 700 0.9893  target1 600
    chr1    400 800 chr1    Mot TF  500 700 0.9893  target1 600
    chr1    100 800 chr1    Mot TF  500 700 0.9893  target1 600
    chr1    100 800 chr1    Mot TF  100 300 0.9893  target1 200
    

    【讨论】:

      【解决方案2】:

      如果您对输出格式很灵活:

      join fileB fileA | awk '$2 < $NF && $NF < $3' 
      
      chr1 500 1000 Mot TF 500 700 0.9893 target1 600
      chr1 400 800 Mot TF 500 700 0.9893 target1 600
      chr1 100 800 Mot TF 500 700 0.9893 target1 600
      chr1 100 800 Mot TF 100 300 0.9893 target1 200
      

      join 不会两次打印连接列。我假设 fileA 的最后一个字段已经是平均值了。

      否则

      awk -v OFS='\t' '
          NR==FNR {f1[$0] = $1; min[$0] = $2; max[$0] = $3; next}
          {
              avg=($4+$5)/2
              for (b in f1) {
                  if ($1 == f1[b] && min[b] < avg && avg < max[b]) {
                      print b, $0
                  }
              }
          }
      ' fileB fileA
      
      chr1    100 800 chr1    Mot TF  500 700 0.9893  target1 600
      chr1    500 1000    chr1    Mot TF  500 700 0.9893  target1 600
      chr1    400 800 chr1    Mot TF  500 700 0.9893  target1 600
      chr1    100 800 chr1    Mot TF  100 300 0.9893  target1 200
      

      【讨论】:

      • 谢谢格伦,这太棒了!你能解释一下你在 $2
      猜你喜欢
      • 1970-01-01
      • 2012-10-13
      • 2017-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-29
      • 1970-01-01
      相关资源
      最近更新 更多