2개의 파일이 있습니다. 첫 번째는 fileA
다음과 같습니다 .
TCONS_00000066 XLOC_000030 - u q1:XLOC_000030|TCONS_00000066|0|0.000000|0.000000|0.000000|0.000000|-
TCONS_00000130 XLOC_000057 - u q1:XLOC_000057|TCONS_00000130|0|0.000000|0.000000|0.000000|0.000000|-
TCONS_00000395 XLOC_000206 - u q1:XLOC_000204|TCONS_00000393|0|0.000000|0.000000|0.000000|0.000000|-
FileB
좋다:
>TCONS_00000001 gene=XLOC_000001
AGATGAGCTGGTGGGGATGCTCTAAGAGAACGAGAGAAGCACAGAGCAGATAAACCACACCCACAGGCAC
CACCGTCCTTGTTGGTAATGAAGAAGACGAGACGACGACTTCCCCACTAGGAAACACGACGGAGGCGGAG
ATGATCGACGGCGGAGAGAGCTACAGAAACATCGATGCCTCCTGTCCAATCCCCCCATCCCATTCGGTAG
TTGGATTGAAGACTACCGAATAAGAGAAGCAGGCAGGCAGACAAACCCTTGAACCAAGGAGTCCTCGCTG
AGGAAGCTTTGGATCCACGACGCAGCTATGGCCTCCCCGCCCACCAGGCCGCCAGCCACAACCAGCTGAC
TAGGTCGCATGCATCATCAGATTTCAATCTCCCTTCGTTCCCTGTCCCTAATCCAATACCAATAGGGAGC
AATCAGCTGCTCCTCGACGGCGAGGGAGATGTCGTCGGCCGCGGGCCAAGACAACGGAGATACCGCTGGG
GACTACATCAAGTGGATGTGCGGCGCCGGTGGCCGTGCGGGCGGCGCCATGGCCAACCTCCAGCGCGGCG
TTGGCTCCCTCGTCCGTGACATTGGCGACCCCTGCCTCAACCCATCCCCCGTTAAGGGGAGCAAAATGCT
CAAACCGGAAAAATGGCACACATGTTTTGATAATGATGGAAAGGTCATAGGTTTCCGTAAAGCCCTAAAA
TTCATTGTCTTAGGGGGTGTGGATCCCACTATTCGAGCTGAAGTTTGGGAATTTCTTCTTGGCTGCTATG
CCTTGAGTAGTACCTCAGAGTATAGGAGGAAACTAAGAGCTGTTAGAAGGGAAAAATATCAAATTTTAGT
TAGACAGTGCCAGAGCATGCACCCAAGCATTGGTACAGGTGAGCTTGCTTACGCTGTTGGATCAAAGCTA
이제 첫 번째 열에 fileA
는 선택한 성적표 번호와 fileB
모든 성적표의 순서가 포함됩니다. fileB
첫 번째 열을 스캔 fileA
하고 성적표 번호와 함께 일치하는 성적표의 후행 시퀀스를 인쇄하고 싶습니다 .
답변1
sed -n 's|^\(TCONS_[0-9]*\) .*|\
/^>\1 /,/\\n>/P|p' fileA |
sed -e '$!N' -f - -e D fileB >outfile
...이것은 당신이 원하는 것을 달성할 것입니다. TCONS_
문자열과 공백 문자로 시작하는 fileA의 각 줄에 대해 첫 번째 sed
줄은 다음과 같은 줄을 인쇄합니다.
/^>TCONS_000001 /,/\n>/P
... 000001
선을 생성하는 일련의 숫자는 어디에 있습니까?
두 번째는 sed
세 개의 스크립트를 제공합니다. 모두 해당 입력 파일인 fileB에 적용됩니다.
첫 번째 명령은 마지막 라인을 제외한 패턴 공간의 모든 라인에 ext 입력 라인을 추가
$!N
하도록 지시합니다 .N
!
$
다음은 stdin입니다. 앞서 언급했듯이 이를 위해 만들어진
-f -
첫 번째 항목 입니다.sed
- 첫 번째는 두 번째의 각 행
sed
에 대해 2개의 주소 범위를 인쇄하고, 두 번째는//,//
패턴 공간의 두 주소 사이에 있는 모든 행에 대해 첫 번째 ewline을sed
인쇄하도록 지시합니다.P
\n
- 첫 번째는 두 번째의 각 행
마지막 스크립트는 단순히 패턴 공간에서 처음으로 나타나는 ewline을 삭제하고 세 스크립트를 모두 다시 시도하도록
D
지시합니다 .sed
D
\n
결과적으로 sed
블록 헤더가 패턴 공간의 선두에 있을 때 두 번째 스크립트의 첫 번째 스크립트와 일치하는 모든 범위가 시작됩니다. ext로 이를 끌어오고 ^
이전 라인 이후의 반복을 삭제하며 다음 라인에서 시작됩니다. 닫는 블록 헤더가 먼저 나타나고 여전히 ewline 문자로 구분된 패턴 공간 뒤에 있습니다. 두 번째 것은 해당 구분 기호보다 더 이상 인쇄하지 않기 때문에 fileB를 한 줄 앞으로 이동하여 fileA의 열 1에 있는 문자열로 시작하는 모든 블록을 인쇄하고 다른 것은 인쇄하지 않습니다.N
D
\n
sed
P
sed
다른(더 복잡하고/더 효율적)방법
세련:
also_fasta()( IFS='
'; get_match_lines(){
tr -s '[:space:]' \\n |
grep "$1" | grep -nFf - "$3"
}
get_script(){
set \\ '\1,$p;n\' '1,\1b\1\' \
'/^>/!b\1|p' '$c\' q
sed -n "s|\([^:]*\).*|:\1$*"
}
get_match_lines "$@" < "$2" |
get_script | sed -nf - "$3"
)
쉘에서 함수를 정의하고 다음과 같이 호출하면:
also_fasta 'TCONS_[0-9]*' fileA fileB
...이제 효과가 있을 것 같아요.
나는 몇 가지 테스트를 한 후에 이것을 알아 냈습니다. 첫 번째는 확실히 작동하지만;느린큰 입력의 경우.
예제의 모든 줄을 [ACGT]*
클립보드에 복사한 후 다음과 같은 샘플 데이터를 만들었습니다.
seq -w -s " gene=XLOC_dummy
$( xsel -bo | sed 's/ *$//')
>TCONS_" 0 512 99999999 >/tmp/temp
seq
위의 내용은 다음과 같은 블록을 작성하는 데 사용됩니다 .
>TCONS_99993600 gene=XLOC_dummy
AGATGAGCTGGTGGGGATGCTCTAAGAGAACGAGAGAAGCACAGAGCAGATAAACCACACCCACAGGCAC
CACCGTCCTTGTTGGTAATGAAGAAGACGAGACGACGACTTCCCCACTAGGAAACACGACGGAGGCGGAG
ATGATCGACGGCGGAGAGAGCTACAGAAACATCGATGCCTCCTGTCCAATCCCCCCATCCCATTCGGTAG
TTGGATTGAAGACTACCGAATAAGAGAAGCAGGCAGGCAGACAAACCCTTGAACCAAGGAGTCCTCGCTG
AGGAAGCTTTGGATCCACGACGCAGCTATGGCCTCCCCGCCCACCAGGCCGCCAGCCACAACCAGCTGAC
TAGGTCGCATGCATCATCAGATTTCAATCTCCCTTCGTTCCCTGTCCCTAATCCAATACCAATAGGGAGC
AATCAGCTGCTCCTCGACGGCGAGGGAGATGTCGTCGGCCGCGGGCCAAGACAACGGAGATACCGCTGGG
GACTACATCAAGTGGATGTGCGGCGCCGGTGGCCGTGCGGGCGGCGCCATGGCCAACCTCCAGCGCGGCG
TTGGCTCCCTCGTCCGTGACATTGGCGACCCCTGCCTCAACCCATCCCCCGTTAAGGGGAGCAAAATGCT
CAAACCGGAAAAATGGCACACATGTTTTGATAATGATGGAAAGGTCATAGGTTTCCGTAAAGCCCTAAAA
TTCATTGTCTTAGGGGGTGTGGATCCCACTATTCGAGCTGAAGTTTGGGAATTTCTTCTTGGCTGCTATG
CCTTGAGTAGTACCTCAGAGTATAGGAGGAAACTAAGAGCTGTTAGAAGGGAAAAATATCAAATTTTAGT
TAGACAGTGCCAGAGCATGCACCCAAGCATTGGTACAGGTGAGCTTGCTTACGCTGTTGGATCAAAGCTA
/tmp/temp
... 문자열의 숫자 부분이 >TCONS_[0-9]*
블록당 512 간격으로 증가하는 파일로 . 전체 파일 크기는 약 185mbs입니다.00000512
99999999
그런 다음 나는 다음을 수행했습니다.
grep -F 00\ </tmp/temp | cut -d\> -f2 >/tmp/tempA
...스키마 파일용(이것은 일치 TCONS_[0-9]*00<space>
하는 항목으로 선택 범위를 좁힙니다.).
두 파일의 줄 수는 다음과 같습니다.
wc -l /tmp/temp*
2734369 /tmp/temp
7813 /tmp/tempA
2742182 total
해당 크기의 입력에 대해서도 두 개의 s를 실행 하지 않았지만 sed
제가 시도한 가장 큰 제안 sed | sed
은 데이터 파일, 해당 크기의 십일조 및 선택한 스키마 파일입니다. 2\
하지만 그와 비슷합니다.
어쨌든, 무슨 일이 일어나고 있는지 생각해 보니 패턴 파일이 8000개의 정규 표현식에 접근함에 따라 한 줄이 올 때마다 D
계속해서 나타나는 이전 정규 표현식을 모두 확인하여 작동해야 한다는 것을 깨달았습니다. 이것은 아마도아니요최선을 다했습니다.
적어도 내가 생성하는 입력에는 나에게 맞는 한 가지가 있습니다. 그것은 다소 연속적입니다. 해당 스레드를 따라가면서 정규식 대신 줄 번호로 작업할 수 있다면 연속적일 필요도 없다는 것을 깨달았습니다 grep
. 그래서 .
내가 실행한 명령(그리고 위 기능의 기초)예:
sed -n 's|^\(TCONS_[0-9]*\) .*|>\1 |p
' < /tmp/tempA |
grep -nFf - /tmp/temp |
sed -n 's|\([^:]*\):.*|:\1\
\1,$p;n;1,\1b\1\
/^>/!b\1|p;$c\' -e q |
sed -nf - /tmp/temp
이것을 사용하는 경우 fileB
for /tmp/temp
및 fileA
for 를 교체해야 합니다 /tmp/tempA
.
grep -F
정규식 대신 고정 문자열을 사용하면 훨씬 빠릅니다.(특히 우리가 1차 경쟁업체와 협력하고 있다는 점을 고려하면)- 나머지는 기본적으로 grep
각 결과의 시작 부분에 반환되는 줄 번호를 제외한 모든 결과를 무시합니다. sed
중간에 있는 내용은 최종적으로 데이터 파일을 처리하는 프로그램이 한 번이라도 스크립트를 역추적하지 않는 방식으로 출력을 처리합니다. 입력을 처리하는 동안 스크립트 파일을 처리합니다 grep
.sed
인쇄된 각 줄의 끝에는 sed
다음과 유사한 내용이 기록됩니다.sed
grep
:2732801 #define branch label :LINENO
2732801,$p #if LINENO thru last line print
n #overwrite current line w/ next line
1,2732801b2732801 #if first line thru LINENO branch to :LINENO
/^>/!b2732801 #if !not /^>/ branch to :LINENO
따라서 각 grep
일치 항목에 대해 sed
두 개의 작은 읽기 루프가 구현됩니다 . 첫 번째는 sed
현재 줄 번호가 증가되는 grep
다음 일치 항목이 나올 때까지 현재 줄을 다음 줄로 덮어쓰는 무작동입니다. 두 번째는 sed
현재 줄이 계속해서 인쇄된 다음 줄이 일치할 때까지 다음 줄로 덮어쓰는 인쇄 루프입니다 /^>/
. 이러한 방식으로 sed
해당 스크립트는 그 안에 있는 파일과 동기적으로 처리됩니다. 즉, 다음 일치하는 줄 번호에 허용되는 것 이상으로 스크립트를 진행하지 않습니다.
이는 다른 스크립트보다 훨씬 더 좋습니다. 그것은 185mbs를 처리합니다 ...
( also_fasta 'TCONS_[0-9]*' /tmp/tempA /tmp/temp; ) \
3.93s user 0.39s system 100% cpu 4.281 total
...다른 하나는 입력 크기의 10%를 처리합니다...
( sed -n 's|^\(TCONS_[0-9]*\) .*|/>\1 /,/\\n>/P|p' /tmp/tempA |sed -e -f... ) \
108.58s user 0.04s system 100% cpu 1:48.56 total
보다 구체적으로 다른 스크립트의 입력 줄 수는 다음과 같습니다.
wc -l /tmp/temp*
273435 /tmp/temp
782 /tmp/tempA
274217 total
답변2
이런 종류의 작업을 자주 수행할 예정이라면 이러한 종류의 작업에 정말 유용한 몇 가지 도구를 사용하는 것이 좋습니다.
FastaToTbl
:#! /bin/sh gawk '{ if (substr($1,1,1)==">") if (NR>1) printf "\n%s\t", substr($0,2,length($0)-1) else printf "%s\t", substr($0,2,length($0)-1) else printf "%s", $0 }END{printf "\n"}' "$@"
파일을
FastaToTbl
in 으로 저장~/bin
하고 실행 가능하게 만듭니다chmod 755 ~/bin/FastaToTbl
.TblToFasta
#! /bin/sh gawk '{ sequence=$NF ls = length(sequence) is = 1 fld = 1 while (fld < NF) { if (fld == 1){printf ">"} printf "%s " , $fld if (fld == NF-1) { printf "\n" } fld = fld+1 } while (is <= ls) { printf "%s\n", substr(sequence,is,60) is=is+60 } }' "$@"
파일을
TblToFasta
in 으로 저장~/bin
하고 실행 가능하게 만듭니다chmod 755 ~/bin/TblToFasta
.
이제 이 두 스크립트가 설정되었으므로 FastaToTbl
FASTA 시퀀스를 Tbl 형식(서열 이름, TAB, 시퀀스)으로 변경하여 다음을 사용하여 더 쉽게 검색할 수 있습니다.
FastaToTbl fileB | grep -f <(awk '{print $1}' fileA) | TblToFasta
스크립트를 사용하여 FastaToTbl
시퀀스와 ID를 동일한 파일에 넣습니다. 검색할 패턴 파일을 요청하는 "file"로 grep에 전달할 수 있는 옵션을 사용하고 있으므로 의 awk '{print $1}' fileA
첫 번째 필드를 인쇄합니다 . 마지막으로 FASTA 형식으로 돌아갑니다.fileA
<()
-f
TblToFasta
마지막으로 내 정보를 확인해 보세요.retrieveseqs.pl
스크립트는 이 작업과 다른 많은 작업을 수행할 수 있습니다. 예를 들어, 이 경우 다음을 수행할 수 있습니다.
retrieveseqs.pl -f fileB fileA
1이 두 스크립트를 처음 작성한 JF Abril에게 감사드립니다 .