嵌套for循环进入和退出多个目录Bash脚本

时间:2018-03-19 00:38:19

标签: bash loops nested

例如,我有7个目录,每个目录包含4个文件。这4个文件遵循以下命名约定name_S#_L001_R1_001.fastq.gz。 sed命令部分保留唯一文件名。

我有一个嵌套的for循环,以便进入目录并执行命令,退出目录并继续下一个目录。一切似乎工作得很漂亮,但代码卡在最后一个目录循环4次。

for f in /completepath/*
do
    [ -d $f ] && cd "$f" && echo Entering into $f
    for y in `ls *.fastq.gz | sed 's/_L00[1234]_R1_001.fastq.gz//g' | sort -u`
    do
        echo ${y}
    done
done

示例输出 -

Entering into /completepath/m_i_cast_avpv_1
iavpvcast1_S6
Entering into /completepath/m_i_cast_avpv_2
iavpvcast2_S6
Entering into /completepath/m_i_int_avpv_1
iavpvint1_S5
Entering into /completepath/m_i_int_avpv_2
iavpvint2_S5
Entering into /completepath/m_p_cast_avpv_1
pavpvcast1_S8
Entering into /completepathd/m_p_int_avpv_1
pavpvint1_S7
Entering into /completepath/m_p_int_avpv_2
pavpvint2_S7
pavpvint2_S7
pavpvint2_S7
pavpvint2_S7

有关如何正确退出内循环的任何建议?

1 个答案:

答案 0 :(得分:0)

看起来/completepath/包含一些不是目录的条目。当/completepath/*上的循环看到的东西不是目录时,由于[ -d $f ]检查,它不会输入它。 但它仍然继续运行下一个for y in ...循环。 此时脚本仍然在它看到的上一个目录中。

解决这个问题的一种方法是在$f不是目录时跳过剩下的循环:

if [ -d $f ]; then
    cd "$f" && echo Entering into $f
else
    continue
fi

还有更好的方法。通过编写/completepath/*/,只会匹配目录条目,因此您可以简化循环:

for f in /completepath/*/
do
    cd "$f" && echo "Entering into $f" || { echo "Error: could not enter into $f"; continue; }
    for y in $(ls *.fastq.gz | sed 's/_L00[1234]_R1_001.fastq.gz//g' | sort -u)
    do
        echo ${y}
    done
done