![根据字段匹配合并 2 个文件](https://linux22.com/image/57177/%E6%A0%B9%E6%8D%AE%E5%AD%97%E6%AE%B5%E5%8C%B9%E9%85%8D%E5%90%88%E5%B9%B6%202%20%E4%B8%AA%E6%96%87%E4%BB%B6.png)
我想创建一个包含两个输入文件中的列的文件。文件1就像:
aa 32
bb 15
cc 78
文件2是:
fa 19
bc 23
cc 50
de 28
aa 45
bb 31
任务是,读取 File1,如果一行的第一个字段存在于 File2 的第一个字段中,则打印 File2 的该行,以及两列,并添加包含第一个字段的 File1 的第二列条目。
输出应该是这样的:
aa 45 32
bb 31 15
cc 50 78
该脚本首选 awk。
答案1
$ awk 'FNR==NR{a[$1]=$2;next} ($1 in a) {print $1,a[$1],$2}' file2 file1
aa 45 32
bb 31 15
cc 50 78
解释:
awk
隐式循环遍历每个文件,一次一行。由于我们将其file2
作为第一个参数,因此首先读取它。 file1
是第二个读的。
FNR==NR{a[$1]=$2;next}
NR
awk
是迄今为止已读取的行数, 是当前文件中迄今为止已读取的FNR
行数。awk
因此,如果FNR==NR
,我们仍在读取第一个命名文件:file2
。对于 中的每一行file2
,我们分配a[$1]=$2
.这里,
a
是一个关联数组表示a[$1]=$2
将 file2 的第二列(表示为 )保存$2
为数组中的值,并a
使用 file2 的第一列$1
作为键。next
指示awk
跳过其余命令并从下一行开始。($1 in a) {print $1,a[$1],$2}
如果我们到达这里,则意味着我们正在读取第二个文件:
file1
.如果我们在 中看到该行的第一个字段file2
(由 array 的内容确定)a
,那么我们会打印出一行,其中包含两个文件中字段 2 的值。
答案2
我喜欢 awk 解决方案,但我认为这可能更容易:
sort file1 > sortedFile1
sort file2 > sortedFile2
join -o 1.1 2.2 1.2 sortedFile1 sortedFile2
该选项-o
将覆盖您选择的第一个文件的第一个字段、第二个文件的第二个字段和第一个文件的第二个字段的格式。
答案3
将第二个文件加入File2
到第一个文件中,File1
.
join <(sort -k1 file2) <(sort -k1 file1)