我想运行一个脚本,搜索每个snp (包含在变量$snplist中的snp列表)是否包含在所有*renamed_snp_search.txt队列中(所有队列位于以*renamed_snp_search.txt结尾的单独文件中)。如果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发布于 2022-02-03 18:28:22
您误解了您所拥有的两个循环的逻辑结构:while [ "$total_snp" -lt 10 ]循环和for snp in $snplist循环。while循环上的条件只在每次通过该循环的开始时进行测试,因此,如果条件在该循环的半路上得到满足,则不会中断该for循环。
本质上,执行过程如下所示:
检查$snplist
$total_snp是否小于10,因此运行while循环的内容:
for循环,搜索$total_snp中的每一项以查看$total_snp是否小于10;如果再次运行while循环的内容,则退出循环。H 216G 217...so如果在所有文件中都找到了10个或10个以上的snp,那么在运行整个snp列表之前,它不会注意到已经找到足够多的snp。
(另一方面,假设所有文件中只有7个snps。在这种情况下,它会搜索所有的snps,找到这7个匹配,检查它是否找到了10个,因为它没有再次运行for循环,并再次查找和记录相同的7个匹配。在此之后,$total_snp将为14,因此它将最终退出while循环。)
相反,您想要做的是,如果for循环运行时$total_snp达到10,则该循环将脱离该循环。因此,删除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
donehttps://stackoverflow.com/questions/70971859
复制相似问题