将两个具有共同模式但具有多个连接的文件连接起来

将两个具有共同模式但具有多个连接的文件连接起来

我有两个文件:

文件 1(sep = 选项卡):

A1 bla blo bli 23 blp
A1 bla blo bli 21 blp
A1 bla blo bli 28 blp
B2 bla blo bli 32 blp
B2 bla blo bli 31 blp
B2 bla blo bli 35 blp

文件 2(sep = ;):

fli;flo;A1;flu;flc
fli;flo;A2;flu;flc
fli;flo;B1;flu;flc
fli;flo;B2;flu;flc

我想将文件 1 中与第 1 个字段的相同值对应的第 5 个(数字)字段的所有值的列表添加到文件 2 中的那些行,其中第 3 个字段与文件 1 的第 1 个字段相同。对于上面的示例输入,所需的输出将如下所示:

fli;flo;A1;flu;flc;23;21;28
fli;flo;A2;flu;flc;
fli;flo;B1;flu;flc;
fli;flo;B2;flu;flc;32;31;35

你有一些awk命令(或其他)来做到这一点吗?

我已经做了一些测试,FNR==NR但还没有开始。

提前致谢

答案1

您应该能够使用以下awk命令完成任务:

awk -F"\t" 'FNR==NR{if ($1 in a) {a[$1]=a[$1] ";" $5} else {a[$1]=$5}} \
            NR>FNR{split($0,f,";"); $0=$0 ";" a[f[3]]; print}' file1 file2

(分成两行以提高可读性)。

这将首先读取file1,并在处理该文件时(由 表示FNR == NR),创建一个映射表a,该表累积$5与同一$1值对应的所有值。

当处理第二个文件 ( NR>FNR) 且表a包含第三个分号分隔字段的值的条目时,该值将附加到该行。

由于不可能指定“每个文件字段分隔符”,因此-F选择的命令行参数对于第一个制表符分隔的文件是正确的。这意味着在处理第二个文件时,必须使用该函数“手动”执行分割,split()并将结果存储在另一个数组中,然后通过而不是f访问其条目(=字段)。f[number]$number

更新我对 Stalin Vignesh Kumar 的回答的说法进行了纠正:毕竟,可以指定每个文件的字段分隔符。)

对于您的示例输入,我得到

fli;flo;A1;flu;flc;23;21;28
fli;flo;A2;flu;flc;
fli;flo;B1;flu;flc;
fli;flo;B2;flu;flc;32;31;35

答案2

$ awk 'FNR==NR{ a[$1]=a[$1]";"$5;next }{sub(";","",a[$3]);print $0";"a[$3]}' file FS=";" file1
fli;flo;A1;flu;flc;23;21;28
fli;flo;A2;flu;flc;
fli;flo;B1;flu;flc;
fli;flo;B2;flu;flc;32;31;35

答案3

$ awk 'NR==FNR{a[$1]=($1 in a ? a[$1] OFS : "") $5; next} {print $0, a[$3]}' OFS=';' file1 FS=';' file2
fli;flo;A1;flu;flc;23;21;28
fli;flo;A2;flu;flc;
fli;flo;B1;flu;flc;
fli;flo;B2;flu;flc;32;31;35

答案4

该块创建一个数组,其中包含从值构建的BEGIN每个值的前缀。$1$5

行代码

$ awk 'BEGIN { while ( (getline <"input.1") > 0) { a[$1]=a[$1] ";" $5; }; FS=";" }; '\
'{ if (a[$3]=="") a[$3]=";"; print $0 a[$3]; }' input.2

fli;flo;A1;flu;flc;23;21;28
fli;flo;A2;flu;flc;
fli;flo;B1;flu;flc;
fli;flo;B2;flu;flc;32;31;35

相关内容