如何使用awk基于前三列合并两个文件

如何使用awk基于前三列合并两个文件,awk,Awk,我想使用前三列作为键将两个文件合并成一行一行。例如: file1.txt a b c 1 4 7 x y z 2 5 8 p q r 3 6 9 file2.txt p q r 11 a b c 12 x y z 13 我希望上述两个文件的输出为: a b c 1 4 7 12 x y z 2 5 8 13 p q r 3 6 9 11 每个文件中的列数不是固定的,它可以随行而异。而且,我在每个文件中都有超过27K行 他们没有订购。唯一的问题是两个文件的前三个字段相同。试试这个: awk

我想使用前三列作为键将两个文件合并成一行一行。例如:

file1.txt

a b c 1 4 7
x y z 2 5 8
p q r 3 6 9
file2.txt

p q r 11
a b c 12
x y z 13
我希望上述两个文件的输出为:

a b c 1 4 7 12
x y z 2 5 8 13
p q r 3 6 9 11
每个文件中的列数不是固定的,它可以随行而异。而且,我在每个文件中都有超过27K行

他们没有订购。唯一的问题是两个文件的前三个字段相同。

试试这个:

 awk 'NR==FNR{a[$1$2$3]=$4;next}$1$2$3 in a{print $0, a[$1$2$3]}' file2 file1 

如果列的长度不同,您可以使用
子集

awk 'NR==FNR{A[$1,$2,$3]=$4; next}($1,$2,$3) in A{print $0, A[$1,$2,$3]}' file2 file1

对于文件1和排序输出中的不同列,请尝试:

awk '{$1=$1; i=$1 FS $2 FS $3 FS; sub(i,x)} NR==FNR{A[i]=$0; next}i in A{print i $0, A[i]}' file2 file1 | sort

您也可以使用
join
,它需要排序输入,并且前3个字段合并。下面的示例对每个文件进行排序,并允许
sed
合并和分离字段:

join <(sort file1.txt | sed 's/ /-/; s/ /-/') \
     <(sort file2.txt | sed 's/ /-/; s/ /-/') |
sed 's/-/ /; s/-/ /'

在字段数可变的前三个字段上联接(四个或更多):


这假设正好有4列。它还假设连接前三列会产生一个唯一的键(对于示例输入为true,但对于真实文件可能不是true)。@OpenSauce OP知道真实文件的格式。如果OP有这个要求,我确实可以修改代码,这一部分很容易修复,但我想指出,以防OP不知道。但更大的问题是“每个文件中的列数不是固定的,它可能会因行而异”。您只在数组中保存
$4
,但我认为您需要在哪个文件中从
$4
循环到
NF
$4列?两者都有?如果我有N列,我该怎么做?非常感谢。file2有7个固定列,但file1可以有3个或更多。如果它适用于具有3列的file1,也可以。我希望它们按照文件1中的方式进行订购。非常感谢。我投票结束这个问题,因为它似乎是一个对工具或解决方案的建议请求,而不是对您自己的代码的帮助请求。这使您的问题脱离StackOverflow的主题。如果这个评估是错误的,并且你确实需要帮助编写你自己的代码,那么请允许我收回我的投票。
a b c 1 4 7 12
p q r 3 6 9 11
x y z 2 5 8 13
{
    # get the forth field until the last
    for (i=4;i<=NF;i++)
        f=f$i" "

    # concat fields
    arr[$1OFS$2OFS$3]=arr[$1OFS$2OFS$3]f;
    # reset field string
    f=""    
}    
END {
    for (key in arr)
        print key, arr[key]    
}
$ awk -f script.awk file1 file2
a b c 1 4 7 12 
p q r 3 6 9 11 
x y z 2 5 8 13