我通过 AWK 命令使用相同的 key 组合了两个不同的文件。 如果与 File1 和 File2 相比没有关键匹配,则只需 将“\t\t\t”改为“\t\t\t”。
我有以下 AWK 命令。
awk -F"\t" '
{key = $1}
NR == 1 {header = key}
!(key in result) {result[key] = $0 ; next}
{ for (i=2; i <= NF; i++) result[key] = result[key] FS $i }
END {
print result[header],"\tValue2","\tValue3","\tValue4"
delete result[header]
PROCINFO["sorted_in"] = "@ind_str_asc" # if using GNU awk
for (key in result) print result[key]
}
' $1 $2 > $3
合并示例 文件1
Key Value1
A 10000
B 20000
C 30000
D 40000
文件2
B 50000 20000 10000
C 20000 10000 50000
然后是预期结果
Key Value1 Value2 Value3 Value4
A 10000 - - -
B 20000 50000 20000 10000
C 30000 20000 10000 50000
D 40000 - - -
我的 AWK 命令显示
Key Value1 Value2 Value3 Value4
A 10000
B 20000 50000 20000 10000
C 30000 20000 10000 50000
D 40000
我已经尝试过像下面这样的一些方法
!(key in result) {result[key] = $0"\t-\t-\t-" ; next}
但看起来这并不能涵盖所有情况。 有人有更好的主意吗? 谢谢!
最佳答案
此解决方案不会硬编码 File2 中有 3 个额外字段
awk '
BEGIN { FS = OVS = "\t" }
NR == FNR {
key = $1
$1 = ""
store[key] = $0
num_extra_fields = NF-1
next
}
FNR == 1 {
printf "%s", $0
for (i=1; i <= num_extra_fields; i++)
printf "%sValue%d", OFS, i+(NF-1)
print ""
next
}
$1 in store {
print $0 store[key]
next
}
{
for (i=1; i <= num_extra_fields; i++)
$(++NF)="-"
print
}
' file2 file1
由于 stackoverflow 显示选项卡的方式,输出看起来有点奇怪
Key Value1 Value2 Value3 Value4
A 10000 - - -
B 20000 20000 10000 50000
C 30000 20000 10000 50000
D 40000 - - -
要修复代码,您需要跟踪 file2 中更新结果的键。改变
{ for (i=2; i <= NF; i++) result[key] = result[key] FS $i }
至
{ updated[key]=1; for (i=2; i <= NF; i++) result[key] = result[key] FS $i }
并在 END block 中进行更改
for (key in result) print result[key]
至
for (key in result) {
if (!(key in updated)) result[key] = result[key] FS "-" FS "-" FS "-"
print result[key]
}
关于linux - awk 要求合并两个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29476542/