Join 使用awk制表符分隔符连接2个以上的表(n个文件)
嗨,我有10多个文件(只有两列),我想用行名连接它们Join 使用awk制表符分隔符连接2个以上的表(n个文件),join,awk,Join,Awk,嗨,我有10多个文件(只有两列),我想用行名连接它们 file1 a 3 b 4 c 6 file2 c 7 b 33 f 56 file3 d 4 e 9 f 44 a 99 Output file1 file2 file3 a 3 0 99 b 4 33 0 c 6 7 0 e 0 0 9 d 0 0 4 f 0 56 44
file1
a 3
b 4
c 6
file2
c 7
b 33
f 56
file3
d 4
e 9
f 44
a 99
Output
file1 file2 file3
a 3 0 99
b 4 33 0
c 6 7 0
e 0 0 9
d 0 0 4
f 0 56 44
下面的链接完全符合我的要求,但它只适用于两个文件
如何对多个(n)文件执行相同操作。shell命令新增功能对于输入文件未排序的情况,需要显式排序。使用过程替换使解决方案保持简单
#/垃圾箱/垃圾箱
#Helper函数-使用所需参数连接
函数j{
连接-a1-a2-oauto-e0“$@”
}
回显“文件1”“文件2”“文件3”
j对于数组的数组,使用GNU awk,并按以下方式排序:
$ cat tst.awk
BEGIN { OFS="\t" }
{ vals[$1][ARGIND] = $2 }
END {
PROCINFO["sorted_in"] = "@ind_str_asc"
printf "%s", OFS
for (fileNr=1; fileNr<=ARGIND; fileNr++) {
printf "%s%s", ARGV[fileNr], (fileNr<ARGIND ? OFS : ORS)
}
for (key in vals) {
printf "%s%s", key, OFS
for (fileNr=1; fileNr<=ARGIND; fileNr++) {
printf "%s%s", vals[key][fileNr]+0, (fileNr<ARGIND ? OFS : ORS)
}
}
}
$ awk -f tst.awk file1 file2 file3
file1 file2 file3
a 3 0 99
b 4 33 0
c 6 7 0
d 0 0 4
e 0 0 9
f 0 56 44
$cat tst.awk
开始{OFS=“\t”}
{vals[$1][argid]=$2}
结束{
PROCINFO[“排序在”]=“@ind\u str\u asc”
打印文件“%s”,OFS
对于(fileNr=1;fileNr通常建议在自己的帖子中发布3件简单的事情,第一件:输入样本,第二件:输出样本,第三件你的努力。因此,请编辑你的帖子并提供更多细节,然后让我们知道当我试图发布样本输入和输出格式变得混乱时,请考虑添加到上一个问题的链接。最好发布简单的样本接近您的实际输入文件,您可以缩短样本并继续发布,让我们清楚了解您的问题。您的样本数据需要是问题中的文本,以便可以轻松复制和粘贴以进行测试,而不是图像。现在我可以格式化输入并将其放入here@Thor,我不知道如何将其与functi一起使用在和echo上,我有10多个文件需要通过管道“|”它们吗"j Oops,我错过了关于大量文件的要点。上述方法适用于少量固定数量的文件。可以使用临时文件进行迭代-但上面基于“awk”的解决方案可能是您想要的。非常感谢@Mortan,这太神奇了,效果完美了,我永远不会使用awk命令的复杂语法。欢迎使用,请参阅下一步该怎么做。@Kran-“awk命令的复杂语法”?不。awk很简单-它只是一个非常精简的C版本,在读取行时用隐式包装;将行拆分为字段….;完成循环。如果你认为它很复杂,那么你就错过了很多东西!实际上我来自生命科学(生物技术)专业的,所以对我来说有点复杂,把这一切都消化掉:-)
echo "key" "file1" "file2" "file3"
j <(sort file1) <(sort file2) | j - <(sort file3) | column -t
key file1 file2 file3
a 3 0 99
b 4 33 0
c 6 7 0
d 0 0 4
e 0 0 9
f 0 56 44
$ cat tst.awk
BEGIN { OFS="\t" }
{ vals[$1][ARGIND] = $2 }
END {
PROCINFO["sorted_in"] = "@ind_str_asc"
printf "%s", OFS
for (fileNr=1; fileNr<=ARGIND; fileNr++) {
printf "%s%s", ARGV[fileNr], (fileNr<ARGIND ? OFS : ORS)
}
for (key in vals) {
printf "%s%s", key, OFS
for (fileNr=1; fileNr<=ARGIND; fileNr++) {
printf "%s%s", vals[key][fileNr]+0, (fileNr<ARGIND ? OFS : ORS)
}
}
}
$ awk -f tst.awk file1 file2 file3
file1 file2 file3
a 3 0 99
b 4 33 0
c 6 7 0
d 0 0 4
e 0 0 9
f 0 56 44