【问题标题】:Expanding an array within a for loop (file list)在 for 循环中扩展数组(文件列表)
【发布时间】:2019-02-05 19:27:26
【问题描述】:

我在使用 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[@]} 部分未正确扩展,因此循环失败。

谢谢!

【问题讨论】:

    标签: arrays bash for-loop


    【解决方案1】:

    我认为问题在于

    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 将扩展通配符(如您所愿)但不会弄乱变量的内容。

    【讨论】:

    • 感谢您提供的所有信息。这很有帮助。并感谢更一般的评论!
    【解决方案2】:

    试试:

    array=( 37 132 253 642 242 42 );
    
    for d in ${array[@]}; do
        INPUT_FILE1="prmrp_*_"$d"_S*_L00?_R1_001.fastq.gz";
        echo ${INPUT_FILE1}
    done
    

    【讨论】:

      猜你喜欢
      • 2014-02-05
      • 1970-01-01
      • 2011-10-20
      • 2021-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-07
      • 1970-01-01
      相关资源
      最近更新 更多