У меня есть следующий сценарий:
#!/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.
Я очень удивлен, потому что это действительно работает, но в некоторых случаях вызывает беспорядок. Позвольте мне показать вам пример:
Входной файл, содержащий хвостовую часть:
>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":
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