我有2个带有2列的tab separated
文件。第1列是数字,第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(公共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
此代码未返回我期望的结果。你知道如何解决吗?
答案 0 :(得分: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
答案 1 :(得分:0)
我会使用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
程序可以将两个文件连接到一个公共值。它确实需要根据连接列对文件进行排序,但是您的示例不是必需的,因此数据文件的内联sort
排序。然后将其输出通过管道传输到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
答案 2 :(得分:0)
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
$