2017-07-01 49 views
0

我的目录中有四个文件:say a.txt; b.txt; c.txt; d.txt。我想加入所有其他文件基于两个公共列的每个文件(即加入与b.txt,c.txt和d.txt a.txt;与a.txt,c.txt和d加入b.txt。 txt;加入c.txt与a.txt,b.txt和d.txt)。为了两个我可以做的文件这样做:基于目录中所有文件的两列加入文件

join -j 2 <(sort -k2 a.txt) <(sort -k2 b.txt) > a_b.txt

我怎样写这个在目录中的所有文件的循环?我试过了下面的代码,但那不起作用。

for i j in *; do join -j 2 <(sort -k2 $i) <(sort -k2 $j) > ${i_j}.txt

任何帮助/方向将是有益的!谢谢。

回答

0

这可能是一个办法做到这一点:

#!/bin/bash 


files=(*.txt) 


for i in "${files[@]}";do 

    for j in "${files[@]}";do 

     if [[ "$i" != "$j" ]];then 

      join -j 2 <(sort -k2 "$i") <(sort -k2 "$j") > "${i%.*}_$j" 

     fi 

    done 

done 
+0

这工作得非常好!非常感谢。你能澄清1)为什么你将文件声明为一个数组,而不仅仅是“for i in”$ {files}“; do'和2)为什么你有一个名为'”的o/p文件$ {i% 。*} _ $ j“'而不是”$ {i%。* _ $ j}“?我尝试了上述两个更改,但只有您的方法有效。 – aram

+0

1)数组的使用是预先使文件循环。因为我们在循环内部创建文件,所以如果我们只是使用'for i in * .txt'或'files = *。txt',第二个循环会选取新创建的文件。如果使用'“$ {files}”',则只能访问数组的第一个元素。 2)''$ {i%。*} _ $ j“'是使用bash子串删除,这是为'$ i'删除'.txt'。以下是一些示例:https://stackoverflow.com/q/16623835/2002514 – archemiro

+0

如果您事先对文件进行排序并循环访问已排序的文件,则可以对此进行优化。它的方式增加了很多额外的工作,因为我们在循环访问时一次又一次地排序相同的文件。 – archemiro