후행 문자 자르기 문제

후행 문자 자르기 문제

다음 스크립트가 있습니다.

#!/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

관련 정보