在for循环(文件列表)中扩展数组

时间:2019-02-05 19:27:27

标签: arrays bash for-loop

使用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[@]}部分无法正确展开,因此循环失败。

谢谢!

2 个答案:

答案 0 :(得分: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将根据需要扩展通配符,但不会弄乱变量的内容。

答案 1 :(得分:0)

尝试:

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