如何使用awk基于前三列合并两个文件
我想使用前三列作为键将两个文件合并成一行一行。例如: file1.txt如何使用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
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