满足条件后循环不会停止 (bash/linux)

While loop not stopping after condition is met (bash/linux)

我想要 运行 一个脚本来搜索每个 snp(snps 列表包含在变量 $snplist 中)是否在所有 GWAS 队列中(所有队列都在以 *[=14 结尾的单独文件中) =]).如果一个 snp 在所有群组中,则该 snp 进入一个日志文件,我希望循环在找到 10 个 snp 后终止。我认为在 while 循环结束时重新定义 $total_snp 变量会有所帮助,但似乎循环在使用示例数据后继续进行。

touch snp_search.log
total_snp=$(cat snp_search.log | wc -l)
files=(*renamed_snp_search.txt)
count_files=${#files[@]}
while [ "$total_snp" -lt 10 ] ; do
    for snp in $snplist ; do
    count=$(grep -wl "${snp}" *snp_search.txt | wc -l)
            if ((count == count_files)) ; then
            echo "$snp was found in all $count_files files" >> ${date}_snp_search.log
            total_snp=$(cat snp_search.log | wc -l)
            fi
     done
done

您误解了两个循环的逻辑结构; while [ "$total_snp" -lt 10 ] 循环和 for snp in $snplist 循环。 while 循环的条件仅在每次循环开始时进行测试,因此如果在该循环的中途满足条件,它不会中断 for 循环。

本质上执行过程是这样的:

  1. 检查$total_snp是否小于10;是的,所以 运行 while 循环的内容:
  2. 运行 for 循环,为 $snplist
  3. 中的每个项目搜索文件
  4. 检查$total_snp是否小于10;如果它是 运行 再次 while 循环的内容,否则退出循环。

...因此,如果在所有文件中找到 10 个或更多 snp,直到 运行 遍历整个 snp 列表时,它才会注意到它已找到足够的。

(另一方面,假设在所有文件中只找到 7 个 snps。在这种情况下,它会搜索所有 snps,找到 7 个匹配项,检查是否找到了 10 个然而,由于它还没有 运行 for 再次循环并再次查找并记录相同的 7 个匹配项。之后 $total_snp 将是 14,因此它最终会退出while 循环。)

您要做的是在 $total_snp 达到 10 时跳出 for 循环,因为 运行s .所以删除 while 循环,并在 for 循环内添加一个 break 条件:

for snp in $snplist ; do
count=$(grep -wl "${snp}" *snp_search.txt | wc -l)
    if ((count == count_files)) ; then
        echo "$snp was found in all $count_files files" >> ${date}_snp_search.log
        total_snp=$(cat snp_search.log | wc -l)
        if [ "$total_snp" -ge 10 ]; then
            break    # Break out of the `for` loop, we found enough
        fi
    fi
done