Проблема с обрезкой хвостовых символов

У меня есть следующий сценарий:

#!/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, я получаю этот беспорядок (могут быть удалены даже другие символы ...).

Интересно, в некоторых случаях это работает, а в некоторых - нет .. Есть ли способ обрезать хвостовые пятерки?

0
11.01.2017, 23:21
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
1
28.01.2020, 02:46

Теги

Похожие вопросы