满足条件后循环不会停止 (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
循环。
本质上执行过程是这样的:
- 检查
$total_snp
是否小于10;是的,所以 运行 while
循环的内容:
- 运行
for
循环,为 $snplist
中的每个项目搜索文件
- 检查
$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
我想要 运行 一个脚本来搜索每个 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
循环。
本质上执行过程是这样的:
- 检查
$total_snp
是否小于10;是的,所以 运行while
循环的内容: - 运行
for
循环,为$snplist
中的每个项目搜索文件
- 检查
$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