如何为SNP批量搜索脚本添加while循环,找到所有文件共有SNP时自动终止
实现方案
完全可以实现找到在所有目标文件中均存在的SNP后自动终止运行的需求,不需要额外嵌套while循环,仅需在原有双层循环的基础上增加存在性标记判断即可,也可根据使用习惯调整为while遍历SNP的形式,核心逻辑一致。
优化后代码(无需额外while循环)
# 提前统计目标文件总数,作为校验基准 shopt -s nullglob snp_files=(*snp_search.txt) file_total=${#snp_files[@]} # 无目标文件时直接退出 if [ $file_total -eq 0 ]; then echo "未找到任何后缀为snp_search.txt的文件" >> ${date}_snp_search.log exit 1 fi for snp in $snplist; do hit_count=0 for file in "${snp_files[@]}"; do if grep -wq "$snp" "$file"; then echo "${snp} was found in $file" >> ${date}_snp_search.log ((hit_count++)) else echo "${snp} was NOT found in $file" >> ${date}_snp_search.log # 当前SNP有一个文件未命中,直接跳出内层循环,无需继续检索剩余文件 break fi done # 命中数量等于文件总数,说明该SNP在所有文件中都存在 if [ $hit_count -eq $file_total ]; then echo "符合要求的SNP已找到:${snp}" >> ${date}_snp_search.log # 跳出外层循环,直接终止程序 break 2 fi done
逻辑说明
- 提前统计所有
snp_search.txt文件的总数作为校验基准,避免无匹配文件时报错 - 遍历每个SNP时初始化命中计数,只要有一个文件未检索到该SNP就直接跳出内层循环,跳过无效检索
- 当某个SNP的命中计数等于文件总数时,说明该SNP存在于所有目标文件中,直接使用
break 2跳出两层循环终止程序,无需手动检查日志 - 如果你需要找到所有符合要求的SNP而非仅第一个匹配项,删除代码中的
break 2即可
如果你需要使用while循环实现的版本
# 先将SNP列表转为数组 snp_arr=($snplist) index=0 snp_len=${#snp_arr[@]} shopt -s nullglob snp_files=(*snp_search.txt) file_total=${#snp_files[@]} while [ $index -lt $snp_len ]; do snp=${snp_arr[$index]} hit_count=0 for file in "${snp_files[@]}"; do if grep -wq "$snp" "$file"; then echo "${snp} was found in $file" >> ${date}_snp_search.log ((hit_count++)) else echo "${snp} was NOT found in $file" >> ${date}_snp_search.log break fi done if [ $hit_count -eq $file_total ]; then echo "符合要求的SNP已找到:${snp}" >> ${date}_snp_search.log break fi ((index++)) done
内容的提问来源于stack exchange,提问作者Spencer K
相关产品推荐
相关产品推荐

