【问题标题】:combining and processing 2 tab separated files in awk and make a new one在 awk 中组合和处理 2 个制表符分隔的文件并创建一个新文件
【发布时间】:2019-06-30 07:38:42
【问题描述】:

我有 2 个包含 2 列的 tab separated 文件。 column1 1 是数字,column 2 是 ID。像这两个例子:

示例文件1:

188 TPT1
133 ACTR2
420 ATP5C1
942 DNAJA1

示例文件1:

91  PSMD7
2217    TPT1
223 ATP5C1
156 TCP1

我想根据第 2 列(列 ID)找到 2 个文件的共同行,并创建一个新的制表符分隔文件,其中有 4 列:column1 是 ID(common ID)column2 是来自 file1、column3 的数字是来自 file2 的数字,column4 是第 2 列和第 3 列的比率的 log2 值(这意味着 log2(column2/column3))。例如,关于 ID“TPT1”:第 1 列是 TPT1,第 2 列是 188,第 3 列是 2217,第 4 列是 log2(188/2217),等于 -3.561494。 这是预期的输出:

预期输出:

TPT1    188 2217    -3.561494
ATP5C1  420 223 0.9133394

我正在尝试在AWK 中使用以下代码:

awk 'NR==FNR { n[$2]=$0;next } ($2 in n) { print n[$2 '\t' $1] '\t' $1 '\t' log(n[$1]/$1)}' file1.txt file2.txt  > result.txt

这段代码没有返回我所期望的。你知道怎么解决吗?

【问题讨论】:

  • 谢谢。不,这是一个不同的
  • 不,这正是您的尝试失败的原因,尽管还有其他问题(您不使用 $1 "\t" $2 作为 n 中的键,所以它将为空) .如果 Awk 脚本使用单引号,则不能在其中使用单引号。切换到双引号或您得到的答案中的解决方法。

标签: awk


【解决方案1】:
$ awk -v OFS="\t" 'NR==FNR {n[$2]=$1;next} ($2 in n) {print $2, $1, n[$2], log(n[$2]/$1)/log(2)}' file1 file2 
TPT1    2217    188  -3.5598
ATP5C1  223     420  0.913346

【讨论】:

  • sn-p 是做什么的?请解释一下。
  • 与OP的尝试相比变化很小。您应该能够从问题中的信息中弄清楚。
【解决方案2】:

我会使用 join 来实际合并文件而不是 awk:

$ join -j2 <(sort -k2 file1.txt) <(sort -k2 file2.txt) |
   awk -v OFS="\t" '{ print $1, $2, $3, log($2/$3)/log(2) }'
ATP5C1  420 223 0.913346
TPT1    188 2217    -3.5598

join 程序将两个文件连接到一个共同的值上。它确实需要根据连接列对文件进行排序,但您的示例不是,因此数据文件的内联 sorting。然后将其输出通过管道传输到 awk 以计算每行数字的 log2 并生成制表符分隔的结果。


使用 perl 的替代方法,如果您关心它,它会为您提供更多的默认精度(并且不想弄乱 awk 的 CONVFMT 变量):

$ join -j2 <(sort -k2 a.txt) <(sort -k2 b.txt) |
   perl -lane 'print join("\t", @F, log($F[1]/$F[2])/log(2))'
ATP5C1  420 223 0.913345617745818
TPT1    188 2217    -3.55980420318967

【讨论】:

    【解决方案3】:

    awk + ​​排序方法

     awk ' { print $0,FILENAME }' ellyx.txt ellyy.txt | sort -k2 -k3 | awk ' {c=$2;if(c==p) { print c,a,$1,log(a/$1)/log(2) }p=c;a=$1 } '
    

    使用给定的输入

    $ cat ellyx.txt
    188 TPT1
    133 ACTR2
    420 ATP5C1
    942 DNAJA1
    
    $ cat ellyy.txt
    91  PSMD7
    2217 TPT1
    223 ATP5C1
    156 TCP1
    
    $ awk ' { print $0,FILENAME }' ellyx.txt ellyy.txt | sort -k2 -k3 | awk ' {c=$2;if(c==p) { print c,a,$1,log(a/$1)/log(2) }p=c;a=$1 } '
    ATP5C1 420 223 0.913346
    TPT1 188 2217 -3.5598
    
    $
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-20
      • 1970-01-01
      • 2014-08-22
      • 1970-01-01
      相关资源
      最近更新 更多