将文本文件与AWK中的所有字段混合在一起



我有 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
$

最新更新