基于关键字循环文件

时间:2017-12-15 11:37:30

标签: bash file loops

我有一个包含文件的文件夹。每个文件的名称可以分为三个部分:名称 - 所有文件都相同; key - 一些关键字,根据这些关键字,文件可以分为3组;结束号码(1..10) - 组内的位置。例如:

  • 第一组文件,由“key 1”

    定义
    name_key1_1
    name_key1_2
    name_key1_3
    ..
    name_key1_10
    
  • 第二组文件,由“key 2”

    定义
    name_key2_1
    name_key2_2
    name_key2_3
    ..
    name_key2_10
    
  • 第三组文件,由“key 3”

    定义
    name_key3_1
    name_key3_2
    name_key3_3
    ..
    name_key3_10
    

现在我需要循环所有文件,目的是将它们传递给某个程序,该程序组合了来自同一组(密钥)的文件。每次我只需要使用相同的密钥传递文件,以便将它们组合在一起(避免在每次处理期间将文件与其他密钥混合)。因此,有3组文件,应使用以下方法创建三个组合文件:

for file in ${input}/*.xtc; do
 file_name=$(basename "$file")
 prog  -f ${input}/${name}_${key}_* -o ${output}/${name}_${key}_combined.xtc -cat
done

在这个例子中,通过执行prog,我需要组合来自每个组的10个文件(使用相同的密钥),避免与来自另一个组的文件混合。

我将非常感谢这个工作流程的实现及其过滤器的应用,例如基于从文件名中获取的自动检测到的组的数量。

2 个答案:

答案 0 :(得分:0)

我建议使用以下代码,假设循环时$ {name}没有改变。

/编辑: 由于@tripleee是对的,我们应该使用find而不是ls

#!/bin/bash
input="/tmp/test/"
output="/tmp/"
name="foo"
for key in $(find ${input} -maxdepth 1 -mindepth 1 -type f -printf "%f\n" | rev| cut -d"_" -f2 | rev | sort | uniq ); do 
    for file in $(find ${input} -maxdepth 1 -mindepth 1 -type f -name \*_${key}_\* -print | sort ); do
        prog  -f ${file} -o ${output}/${name}_${key}_combined.xtc -cat
    done
done
  1. 查找输入目录中的所有文件。
  2. 从文件名中提取倒数第​​二个字段(a.k.a.关键字);
  3. 对所有关键字进行排序并仅打印一次。
  4. 对于每个关键字,找到包含该关键字的文件。
  5. 将该文件传递给您的编程。
  6. 完成。

答案 1 :(得分:0)

如果字段由下划线分隔,并且值中没有其他下划线(即所有文件名只包含两个下划线),则只需在下划线上拆分。

for file in ${input}/*.xtc; do
    oldIFS=$IFS
    IFS=_
    set -- ${file#"$input"/}
    IFS=$oldIFS
    dest="${output}/${1}_${2}_combined.xtc"
    test -e "$dest" && continue
    prog  -f "${input}/${1}_${2}_"{1..10} -o "$dest" -cat
done

命令set -- stringstring的值$IFS拆分为$1,并填充位置参数$2$3${variable#prefix}等结果。参数展开$variable会返回prefix的值,并删除prog(如果找到)。

我们粗暴地遍历所有文件,但如果输出文件已经存在,请跳过 base=${file%_*} tail=${file#"$base"} head=${base%_"$tail"} dest="$outputdir/${head#$input/}_combined.txt" test -e "$dest" && continue :

如果您需要从末端剥离下划线,可能会在循环内部出现这样的情况:

${variable#suffix}

其中@user删除后缀。

如果您可以重新设计输入的结构,那么组 - 以及它们之前的名称 - 也是子目录,这将使得处理集合时没有任何其他逻辑非常自然和直接。

相关问题