我有 2 个制表符分隔的文件,如下所示:
示例 1:
RBM3 1517 993 -0.611355
RBM4 142 142 0
PRKAG1 146 73 -1
MORF4L2 1766 715 -1.30447
例2:
PCNP 370 139 -1.41244
RBM3 60 60 0
COTL1 338 252 -0.4236
PRKAG1 276 225 -0.294743
我想获取基于第 1 列(在两个文件中(的公共行,并创建一个包含 7 列的新文件,其中第一列是原始文件中的第一列,第 2、3 和 4 列来自第一个文件,第 5、6 和 7 列来自第 2 个文件(第 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
但结果并不正确。你知道怎么解决吗?
这是一种方法:
$ 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
再一次,加入比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
请参阅我在另一篇文章中的回答,了解为什么对文件进行排序;如果您使用我的解决方案来生成这些输入文件,它们已经被排序,您可以直接使用这些文件。这次它使用 sed 来确保输出具有制表符分隔的列。
正如评论中指出的那样,一些shell(bash,zsh,其他(允许您使用$'t'
来获取制表符。在这些上,您可以使用join -t $'t' -j1 sortedfile1.txt sortedfile2.txt
并省略sed位。不过,其他像dash这样的版本则没有,所以第一个版本更便携。
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
$