我有两个文件:
文件 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