我有以下脚本:
#!/bin/bash
SINGLE=`cut -c 7-21 Data.txt`
cd ../FASTA_SEC/
for i in ${SINGLE}; do
if [ -r ../FASTA_SEC/${i}.fa ]; then
HEAD=`sed -n 2p ../FASTA_SEC/${i}.fa | head -c 3`
TAIL=`tail -c 4 ../FASTA_SEC/${i}.fa`
if [ "${HEAD}" = "AAA" ]
then
echo "Cut heading A's" $i
elif [ "${TAIL}" = "AAA" ]
then
echo "Cut tailing A's" $i
while [ `tail -c 2 ../FASTA_SEC/$i.fa` == "A" ]
do
TRITAIL=`cat ../FASTA_SEC/$i.fa`
echo ${TRITAIL/A/} > ../FASTA_SEC/$i.fa
done
fi
else
echo "does not exist" $i
fi
done
它似乎适用于所有已处理的文本文件,包括 while 循环。但是有几个文本文件中所有 A 都被删除,并且引入了一些空格,而不是仅删除尾随的 A。
我很惊讶,因为它确实有效,但在某些情况下它会产生混乱。让我给你看一个例子:
包含 A 尾部的输入文件:
>B4-0K032_18670_015
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNGNNNTAGATACAAGCGAGCGGC
GGACGGGTGAGTAACACGTGGGTAACCTGCCCAAGAGACTGGGATAACACCTGGAAACAG
[Cuted here for shortness]
GGNTGTCNTCNGCTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNAAAAAAAA
输出混乱的文件:
>G4-0K047_18670_010 NNNNNNNNNNCCNCCTGTNNNTTTGCCCCCGGGGGCCTGTCTCTCGGTGTC GTGTCGCCTGGTGGTTCTTCGCGTTGCTTCGTTCCCTGCTCCC
[Cuted here for shortness]
CGTCCGCCNTCGTTCCTGNTGTCTCGGTGCNNGCCCGTNTNNNNNNNNNN NNNNNNNNNNNNN
我只想剪切尾部 A,但在某些文本文件中会出现混乱,但在大多数文本文件中它工作顺利。在一些应该修剪尾部 A 的文件中,我得到了这个混乱(甚至其他字符也可能被删除......)。
我想知道它在某些情况下确实有效,但在某些情况下却不起作用。有没有办法修剪尾部 A?
答案1
整个脚本最终取决于这两行来删除尾随的“A”:
tritail=$(cat ../FASTA_SEC/$i.fa)
echo ${tritail/A/} > ../FASTA_SEC/"$i".fa
由于您已经将整个文件内容放入变量中,因此不需要循环来删除所有尾随的 A。你可以这样做:
tritail="$(cat ../FASTA_SEC/"$i".fa)"
shopt -s extglob
echo ${tritail#+(A)} > ../FASTA_SEC/"$i".fa
或者,如果您不喜欢更改 extglob 设置:
tritail="$(cat ../FASTA_SEC/"$i".fa)"
echo "${tritail%"${tritail##*[!A]}"}" > ../FASTA_SEC/"$i".fa
事实上,这两个命令就足以删除尾随的 A。
第二行的工作原理是选择所有尾随的 A。或者,正如该命令实际执行的那样,通过删除所有内容不是变量前导部分有一个 A ([!A]):
tail=${tritail##*[!A]} # Select all the trailing A's
然后,从变量的尾部删除生成的字符串:
result=${tritail%"$tail"} # Remove the trailing A's
两个参数扩展都连接到一个命令中:
result=${tritail%"${tritail##*[!A]}"}
这就是发送到(修改后的)文件的内容:
echo "${tritail%"${tritail##*[!A]}"}" > ../FASTA_SEC/"$i".fa
要删除前导 A,请切换所有选择:
echo "${tritail#"${tritail%%[!A]*}"}" > ../FASTA_SEC/"$i".fa