我有2个制表符分隔的文件,例如这些小示例:
example1:
RBM3 1517 993 -0.611355
RBM4 142 142 0
PRKAG1 146 73 -1
MORF4L2 1766 715 -1.30447
example2:
PCNP 370 139 -1.41244
RBM3 60 60 0
COTL1 338 252 -0.4236
PRKAG1 276 225 -0.294743
我想获取基于第1列的公共行(在两个文件中),并创建一个包含7列的新文件,其中第1列是原始文件中的第1列,第2、3和4列来自第一个文件以及第5、6和7列来自第二个文件(第2、3和4列)。这是预期的输出:
预期输出:
RBM3 1517 993 -0.611355 60 60 0
PRKAG1 146 73 -1 276 225 -0.294743
我正在尝试使用以下代码在AWK中做到这一点:
awk -v OFS="\t" 'NR==FNR {n[$2]=$1;next} ($2 in n) {print $1, $2, $3, $4, n[$2], n[$3], n[$4]}' file1 file2 > results.txt
,但结果不正确。你有什么办法解决吗?
答案 0 :(得分:1)
这是一种方法:
$ awk -v OFS="\t" '
NR==FNR { # file2
k=$1 # set key
$1="" # nullify $1, OFS stays
a[k]=$0 # hash record on k
next
}
($1 in a) { # file1, if $1 matches in a
print $0 a[$1] # output record and a
}' file2 file1 # mind the order
RBM3 1517 993 -0.611355 60 60 0
PRKAG1 146 73 -1 276 225 -0.294743
使用您的方法将类似于(未测试):
$ awk -v OFS="\t" '
NR==FNR {
n[$1]=$2; o[$1]=$3; p[$1]=$4
next
}
($1 in n) {
print $1, $2, $3, $4, n[$1], o[$1], p[$1]
}' file2 file1 > results.txt
答案 1 :(得分:1)
再一次,join比awk更好:
$ join -j1 <(sort -k1 file1.txt) <(sort -k1 file2.txt) | sed 's/ /\t/g'
PRKAG1 146 73 -1 276 225 -0.294743
RBM3 1517 993 -0.611355 60 60 0
请参阅另一篇文章中的my answer,了解为什么要对文件进行排序;如果您正在使用我的解决方案来生成这些输入文件,则将对它们进行排序,您可以直接使用这些文件。这次使用sed来确保输出具有制表符分隔的列。
正如评论中指出的那样,某些shell(bash,zsh等)使您可以使用$'\t'
来获取制表符。在这些上,您可以使用join -t $'\t' -j1 sortedfile1.txt sortedfile2.txt
并保留sed位。但是,像dash这样的其他工具却没有,所以第一个版本更便于移植。
答案 2 :(得分:0)
sort + awk
sort elly1.txt elly2.txt | awk ' {c=$1; if(c==p) {$1=""; print c,a,$0 } p=c;$1="";a=$0 } ' | sed 's/ +/\t/g'
具有给定的输入
$ cat elly1.txt
RBM3 1517 993 -0.611355
RBM4 142 142 0
PRKAG1 146 73 -1
MORF4L2 1766 715 -1.30447
$ cat elly2.txt
PCNP 370 139 -1.41244
RBM3 60 60 0
COTL1 338 252 -0.4236
PRKAG1 276 225 -0.294743
$ sort elly1.txt elly2.txt | awk ' {c=$1; if(c==p) {$1=""; print c,a,$0 } p=c;$1="";a=$0 } ' | sed 's/ +/\t/g'
PRKAG1 146 73 -1 276 225 -0.294743
RBM3 1517 993 -0.611355 60 60 0
$