有没有一个好的方法来执行'完全外部连接'多个文件在Unix上理想地使用GNU核心utils。我的文件是由uniq -c
生成的,下面是一个可以生成的模拟示例:
echo "12 aa\n3 bb" > file1
echo "5 aa\n6 bb\n1 cc" > file2
echo "11 aa\n7 bb\n4 dd" > file3
看起来像:
tail -n +1 file*
==> file1 <==
12 aa
3 bb
==> file2 <==
5 aa
6 bb
1 cc
==> file3 <==
11 aa
7 bb
4 dd
我想一个接一个地合并它们,使用序列(第2列)作为键,如果键不包含(外部连接),则填充0。也就是说,期望的输出看起来像这样
12 5 11 aa
3 6 6 bb
0 1 0 cc
0 0 4 dd
到目前为止,我发现join
至少可以完成成对合并的工作:
join -j2 file1 file2 -a 2 -a 2 -e '0' -o '1.1,2.1,0' > merged
# 12 5 aa
# 3 6 bb
# 0 1 cc
注意:j2:查看第二列的key(对于两个文件)-a FILENUM:我还可以打印文件FILENUM中不可配对的行,其中FILENUM为1或2,对应于文件1或文件2
但我不知道如何将其推广到多个文件,即。这一个不工作,这意味着我不能很容易地把它放在一个循环中:
join -j2 merged file3 -a 2 -a 2 -e '0' -o '1.1,2.1,0' > merged2
我最好不要使用SQL来实现这一点,但如果没有其他方法也可以。
2条答案
按热度按时间oipij1gg1#
如果你有时间学习如何使用grep、sed和awk,你可以做你想做的事情。
否则,您可以使用此低效解决方案:
此脚本中使用的基本工具是shell的
read
内置命令。有了它,你可以parse a file line by line。原则是:对于每个“行”(aa,bb,cc,dd),使用grep获取该行在每个文件(file1,file2,file3)中出现的次数。有了这些信息,你就可以生产出你想要的产品。
0ve6wy6x2#
最后,使用以下bash脚本
multi_join_from_uniq.sh
打包的sort
找到了一个有效的解决方案:然而,该脚本仅适用于已排序和已交换的列,这可以作为进程替换来完成,以使此示例工作:
产生以下输出:
当然,这也可以在管道传输uniq命令的输出时完成,例如。这样
cat data.txt | uniq -c | awk '{print $2,$1}' | sort > file1
左右。