首页 > 解决方案 > 如何在 while 循环中创建 if 语句以仅在某些行上执行某些操作?

问题描述

我正在尝试编写一个在 sh 中启动的简单 bash 脚本,它允许我从输入文件开始创建一个新的输出文件,并保持以 ">" 开头的每一行在其位置,而对于不满足此要求的每一行,它必须删除每三个字符,然后将其挂在新文件中。

输入文件:

>0197_16S  
-AAAAACATGTCCTCTTGTTTATA-----TNTGAGGTTTGACCTGCCCTATG--A---  
>0688_16S    
-----ACATCTTCTCTTGAGTTAT-----TTTGAGATATGACCTGCCCAATG--A-T-  
.  
.  
.  
.  

sh脚本:

while IFS= read line; do  
if [ "$line" = ">"* ]; then echo "$line" >> output.txt  
else
var=$(echo "$line" | awk -vFS= '{for (i = 1; i <=NF; i+3) {printf $i(i+1)} printf "\n"}');  
echo "$var" >> output.txt  
fi;  
done <foo.txt  

else 语句似乎有效,但是从未验证 if 的条件,也从以字符“>”开头的行中消除每三个字符。

实际输出:

>09716  
-AAACAGTCTTTTTAT----NTAGTTGACTCCTAG-A--  
>08816
----CACTCTTTAGTA----TTAGTAGACTCCAAG-A--  
.  
.  
.  

预期输出:

>0197_16S  
-AAACAGTCTTTTTAT----NTAGTTGACTCCTAG-A--  
>0688_16S  
----CACTCTTTAGTA----TTAGTAGACTCCAAG-A--  
.  
.  
.  

标签: bash

解决方案


尝试避免 while 循环。

没有条件keeping each line starting with ">" in its first position你可以做

sed -r  's/(..)./\1/g' foo.txt

>可以通过更改所有不匹配的行来为行添加条件

sed -r  '/^>/ !s/(..)./\1/g' foo.txt

或与awk

awk '/^>/ {print;next} {print gensub(/(..)./,"\\1", "g")}' foo.txt

推荐阅读