首页 > 解决方案 > 在 for 循环中扩展数组(文件列表)

问题描述

使用 for 循环对文件进行交互时遇到问题。为简单起见,我创建了一个小循环来解释我目前遇到的问题。

起点:文件夹中的文件,在其文件名的定义位置具有文件特定的一到三位数字。

目标:使用 for 循环遍历其中一些文件(不是全部)。

问题:我创建了一个数组,其中包含每个文件特定的一到三位数字。这些文件在 for 循环的开头被调用,我想使用数组来引用特定文件。但是:数组没有正确扩展。

希望有人能帮忙!(可能有几种很好的替代方法可以做到这一点。也许其中一些不需要数组,但我有兴趣了解我的具体问题的解决方案,因为我认为这可能是对如何扩展变量的根本误解作为 for 循环开头的文件名的一部分。)

这是代码:

declare -a SOME_SAMPLES=(37 132 253 642 242 42)

for d in prmrp_*_${SOME_SAMPLES[@]}_S*_L00?_R1_001.fastq.gz; do

    INPUT_FILE1=$(echo $d | sed 's/_L00._R1_001.fastq.gz//')
    echo ${INPUT_FILE1}

done

同样,这只是一个示例代码。问题是${SOME_SAMPLES[@]}没有正确扩展的部分,因此循环失败。

谢谢!

标签: arraysbashfor-loop

解决方案


我认为问题在于

prmrp_*_${SOME_SAMPLES[@]}_S*_L00?_R1_001.fastq.gz

它不会为数组的每个元素复制整个表达式,它只是在中间盲目地插入数组的元素,相当于:

prmrp_*_37 132 253 642 242 42_S*_L00?_R1_001.fastq.gz

...这是一堆单独的项目(prmrp_*_37作为通配符表达式,后跟132作为简单字符串,然后是253等)。AIUI 你要扩展数组的内容,然后对每个元素使用通配符表达式来获取所有匹配的文件。最好的方法是使用两个循环,一个用于扩展数组,另一个用于查找匹配的文件:

for sample in "${SOME_SAMPLES[@]}"; do
    for d in prmrp_*_"${sample}"_S*_L00?_R1_001.fastq.gz; do
        ...

顺便说一句,我还建议使用小写或混合大小写的变量名称(例如sample上面),以避免与许多具有特殊含义/功能的全大写变量可能发生冲突。另外,我会使用参数扩展来删除文件名的后缀(而不是sed):

input_file1=${d%_L00?_R1_001.fastq.gz}

此外,您通常应该在变量引用周围加上双引号(例如echo "${input_file1}",而不是echo ${input_file1})。(像这样的赋值input_file1=${d...是一个例外,尽管双引号在那里并没有什么坏处;它们只是不需要。)请注意,在上面的for循环中,我在数组和变量引用周围加上了双引号,而不是在通配符周围;这意味着 shell 将扩展通配符(如您所愿)但不会弄乱变量的内容。


推荐阅读