根据匹配列合并许多文件

OXX*_*XXO 3 bash awk

我有很多文件(我以5为例)

如果与第一个文件不匹配,则应在输出中附加0

文件1

1001 1 2
1002 1 2
1003 3 5
1004 6 7
1005 8 9
1009 2 3
Run Code Online (Sandbox Code Playgroud)

文件2

1002 7
1003 8
Run Code Online (Sandbox Code Playgroud)

文件3

1001 5
1002 3
Run Code Online (Sandbox Code Playgroud)

文件4

1002 10
1004 60
1007  4
Run Code Online (Sandbox Code Playgroud)

文件5

1001 102
1003 305
1005 809
Run Code Online (Sandbox Code Playgroud)

期望的输出

1001 1 2 0 5  0 102
1002 1 2 7 3 10   0
1003 3 5 8 0  0 305
1004 6 7 0 0 60   0
1005 8 9 0 0  0 809
1007 0 0 0 0  4   0
1009 2 3 0 0  0   0
Run Code Online (Sandbox Code Playgroud)

使用下面的代码,我可以合并两个文件,但是如何合并所有文件

awk 'FNR==NR{a[$1]=$2;next}{print $0,a[$1]?a[$1]:"0"}' file2 file1

1001 1 2 0
1002 1 2 7
1003 3 5 8
1004 6 7 0
1005 8 9 0
Run Code Online (Sandbox Code Playgroud)

提前致谢

kva*_*our 5

GNU加入救援!

$ join -a1 -a2 -e '0' -o auto file1 file2 \
  | join -a1 -a2 -e '0' -o auto - file3   \
  | join -a1 -a2 -e '0' -o auto - file4   \
  | join -a1 -a2 -e '0' -o auto - file5
Run Code Online (Sandbox Code Playgroud)

选项-a1-a2告诉join以插入缺少的字段。并-e '0'告诉它用零代替它们。指定-o auto要假定所有字段的输出。

当有大量文件时,不能使用管道构造,但可以使用简单的for循环:

out=output
tmp=$(mktemp)
[[ -e "$out" ]] && rm -rf "$out" || touch "$out"
for file in f*; do
    join -a1 -a2 -e0 -o auto "$out" "$file" > "$tmp"
    mv "$tmp" "$out"
done
cat "$out"
Run Code Online (Sandbox Code Playgroud)

或者,如果您真的喜欢管道:

pipeline="cat /dev/null"
for file in f*; do pipeline="$pipeline | join -a1 -a2 -e0 -o auto - $file"; done
eval "$pipeline"
Run Code Online (Sandbox Code Playgroud)

这里很有意思: 我可以使用多少个管道?


注意:auto在这种情况下,的用法非常有用,但不是POSIX标准的一部分。它是GNU扩展,是GNU coreutils的一部分。纯粹的POSIX版本会比较麻烦:

$ join -a1 -a2 -e '0' -o 0 1.2 2.2 file1 file2 \
  | join -a1 -a2 -e '0' -o 0 1.2 1.3 2.2 - file3 \
  | join -a1 -a2 -e '0' -o 0 1.2 1.3 1.4 2.2 - file4 \
  | join -a1 -a2 -e '0' -o 0 1.2 1.3 1.4 1.5 2.2 - file5
Run Code Online (Sandbox Code Playgroud)

有关更多信息 man join

  • ++ ve非常棒,感谢您分享。 (2认同)
  • 可能想澄清一下`auto`是GNU扩展。如果OP使用的操作系统不使用GNU coreutils版本,则将无法使用。(当然,这些文件需要在连接字段中排序,它们在OP的示例中。) (2认同)