【问题标题】:join file based on two columns for ALL files in directory基于目录中所有文件的两列加入文件
【发布时间】:2017-07-01 23:10:42
【问题描述】:

我的目录中有四个文件:比如 a.txt; b.txt; c.txt; d.txt。我想将每个文件与基于两个常见列的所有其他文件连接起来(即将 a.txt 与 b.txt、c.txt 和 d.txt 连接;将 b.txt 与 a.txt、c.txt 和 d.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

任何帮助/指导都会有所帮助!谢谢。

【问题讨论】:

    标签: bash loops sorting join


    【解决方案1】:

    这可能是一种方法:

    #!/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
    

    【讨论】:

    • 这很好用!!!非常感谢。您能否澄清 1)为什么将文件声明为数组而不仅仅是 for i in "${files}";do 和 2)为什么您有名为 "${i%.*}_$j" 的 o/p 文件而不是 "${i%.*_$j} “?我尝试了上述两个更改,但只有你的方法有效。
    • 1) 数组的用途是预先拥有要循环的文件。因为我们在循环内创建文件,所以如果我们只使用for i in *.txtfiles=*.txt,第二个循环将获取新创建的文件。如果您使用"${files}",您将只能访问数组的第一个元素。 2) "${i%.*}_$j" 正在使用 bash 子字符串删除,这是为了删除 .txt 只是为了 $i。以下是一些示例:stackoverflow.com/q/16623835/2002514
    • 如果您事先对文件进行排序并遍历已排序的文件,则可以对此进行很多优化。它的方式增加了很多额外的工作,因为我们在遍历它们时一次又一次地对相同的文件进行排序。
    • 感谢您的解释!非常清楚。我将在循环之前对所有文件进行排序。
    猜你喜欢
    • 2020-08-02
    • 1970-01-01
    • 2018-06-25
    • 2017-02-16
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    相关资源
    最近更新 更多