다음 일치 전에 일치 항목과 모든 항목을 추출합니다. 각 일치 항목에 대해 이 작업을 수행합니다.

다음 일치 전에 일치 항목과 모든 항목을 추출합니다. 각 일치 항목에 대해 이 작업을 수행합니다.

다음과 같은 구조의 파일이 있습니다.

>Cluster 0
0       51aa, >MG00HS05:520:C8M1TACXX:3:1101:1428:2080/1... *
1       51aa, >MG00HS05:520:C8M1TACXX:3:1101:1658:2480/1... at 3:51:1:49/96.08%
2       51aa, >MG00HS05:520:C8M1TACXX:3:1101:15131:2756/1... at 1:51:1:51/100.00%
[thousands of similarly looking lines]
>Cluster 1
0       51aa, >MG00HS05:520:C8M1TACXX:3:1101:3733:2088/1... *
1       50aa, >MG00HS05:520:C8M1TACXX:3:1101:6962:2026/1... at 2:50:1:49/98.00%
2       51aa, >MG00HS05:520:C8M1TACXX:3:1101:14617:2071/1... at 2:51:1:50/96.08%
[thousands of similarly looking lines]
>Cluster 2
0       51aa, >MG00HS05:520:C8M1TACXX:3:1101:5164:2153/1... *
1       51aa, >MG00HS05:520:C8M1TACXX:3:1101:15660:20057/1... at 1:51:1:51/98.04%
2       51aa, >MG00HS05:520:C8M1TACXX:3:1101:8563:35493/1... at 1:50:1:51/96.08%
[thousands of similarly looking lines]

로 시작하는 줄 수는 >약 200만 줄입니다.

>다음 줄을 추출하지 않고 시작하는 줄과 그 뒤의 줄을 추출 >하여 파일에 넣고 싶습니다 . 이 같은:

파일 1:

>Cluster 0
0       51aa, >MG00HS05:520:C8M1TACXX:3:1101:1428:2080/1... *
1       51aa, >MG00HS05:520:C8M1TACXX:3:1101:1658:2480/1... at 3:51:1:49/96.08%
2       51aa, >MG00HS05:520:C8M1TACXX:3:1101:15131:2756/1... at 1:51:1:51/100.00%
[thousands of similarly looking lines]

문서 2

>Cluster 1
0       51aa, >MG00HS05:520:C8M1TACXX:3:1101:3733:2088/1... *
1       50aa, >MG00HS05:520:C8M1TACXX:3:1101:6962:2026/1... at 2:50:1:49/98.00%
2       51aa, >MG00HS05:520:C8M1TACXX:3:1101:14617:2071/1... at 2:51:1:50/96.08%
[thousands of similarly looking lines]

파일_3

>Cluster 2
0       51aa, >MG00HS05:520:C8M1TACXX:3:1101:5164:2153/1... *
1       51aa, >MG00HS05:520:C8M1TACXX:3:1101:15660:20057/1... at 1:51:1:51/98.04%
2       51aa, >MG00HS05:520:C8M1TACXX:3:1101:8563:35493/1... at 1:50:1:51/96.08%
[thousands of similarly looking lines]

Bash에서 이 작업을 수행하도록 되어 있는 스크립트를 작성했지만 작동하지 않습니다. 저는 bash 스크립팅 전문가가 아닙니다.

mkdir FemaleMito1_clusters
while read i
        do $i > FemaleMito1_clusters/FemaleMito1_${i#>}
        n=1
        while [ `grep -A $n $i FemaleMito1_cdhit2 | tail -n1 | grep -c "^>"` -eq 0 ]
                do grep -A"$n" $i FemaleMito1_cdhit2 | tail -n1 >> FemaleMito1_clusters/FemaleMito1_"${i#>}"
                ((n++))
                done
        done < FemaleMito1_cdhit2_list #this is a file containing just the lines starting with >

어떻게 해야 합니까? 내 스크립트를 완전히 건너뛰어도 됩니다. 내가 원하는 것을 수행하는 줄이 있을 수 있습니다.

또한 파일을 필터링하고 특정 줄 번호 위에 있는 파일만 유지해야 합니다. 파일을 생성한 후 간단하게 할 수 있는 방법을 생각해봤는데 wc -l, 쓸데없는 파일을 생성하지 않고 명령어에 포함시킬 수 있는 방법이 있으면 좋을 것 같습니다.

답변1

awk에서는 이 작업을 쉽게 수행할 수 있습니다.

awk '{ if(/^>/){name=$0; sub(/^>/,"", name);}{print >> name".fa"}}' file.fa 

이것은 입력 파일의 모든 줄을 반복하고 첫 번째 문자가 이면 >줄을 로 저장 합니다. 그런 다음 파일 이름에 해당 내용을 원하지 않기 때문에 에서 내용을 제거 name합니다 . 마지막으로, 각 행은 현재 시퀀스의 이름이 무엇이든 where 라는 파일 에 추가됩니다 .>namename.faname

N 라인보다 긴 시퀀스만 인쇄하려면 다음을 사용할 수 있습니다.

awk -v min=4 '{ 
               if(/^>/){ 
                    if(num >= min){
                        print seq >> name".fa"
                    } 
                    name=$0; 
                    sub(/^>/,"", name); 
                    seq=$0; 
                    num=0
                }
                else{
                    seq = seq"\n"$0; 
                    num++
                }
               }
               END{
                 if(num >= min){
                    print seq >> name".fa"
                 }
               }' file.fa 

기본 원칙으로는,텍스트 처리에 쉘 루프를 사용하지 마십시오. 느리고 투박하며 오류가 발생하기 쉽습니다.

답변2

(귀하의 의견에서 제안한 대로) 귀하의 응용 분야에 더 적합한 생물정보학 도구가 있을 수 있지만 다음을 사용하여 수행할 수 있습니다 csplit.

csplit -sz file '/^>/' '{*}'

주어진

$ head xx*
==> xx00 <==
>Number_one
[some thousands lines]

==> xx01 <==
>Number_two
[some other thousands lines, less than the latter]

==> xx02 <==
>Number_three
[Some other hundreds lines]

출력 파일 이름의 번호 지정 및 형식 지정에 대한 옵션은 매뉴얼 페이지( man csplit) 를 참조하십시오.

관련 정보