특정 열을 기준으로 한 행을 두 행으로 분해

특정 열을 기준으로 한 행을 두 행으로 분해

.tsv다음을 포함하는 파일( batch_1.catalog.tags.tsv) 이 있습니다.1,965,056행 14열.그 중 일부를 두 줄로 나누고 싶습니다.

첫번째 줄: 보다 큼 기호(>)로 시작하고 그 뒤에 14개 열 중 8개 열이 옵니다.
두 번째 줄: 10열만

예를 들어.

>column3(a number) column4(numbers and letters) column5(a number) column6(- or +) column11(0 or 1) column12(0 or 1) column13(0 or 1) column14(0 or 1)       
column10(string with As,Ts,Gs,Cs, and sometimes Ns)    

.tsv다음은 세 번째 열에 지정된 파일의 여섯 번째 줄의 예입니다 .

0   1   6   gi|586799556|ref|NW_006530744.1|    141 +   consensus   0   1_33,14_43  CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC    0   0   0   0    

이것이 내가 원하는거야:

>6 gi|586799556|ref|NW_006530744.1| 141 +  0 0 0 0        
CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC    

그러나 세 번째 열 번호가 다른 텍스트 파일(whitelist.txt)의 번호와 일치하는 tsv 파일(batch_1.catalog.tags.tsv)의 행에 대해서만 이 작업을 수행하고 싶습니다.

위의 예에서는 whitelist.txt세 번째 열 번호(예: ID)가 서로 다른 행이 8000개 이상 있지만 파일에는 숫자 6이 포함됩니다. 여기에는 whitelist.txt최대 6자리 숫자가 포함됩니다.

나는 다른 접근 방식을 시도해 왔습니다. 화이트리스트를 사용하여 파일에서 10번째 열을 추출하는 코드는 다음과 같습니다 .tsv. 그러나 grep은 10시간 동안 계속 진행되었으며 아무 작업도 수행하지 않았습니다(빈 cat.fa파일).

cat whitelist.txt | while read line; do zgrep "^0    1       $line   " batch_1.catalog.tags.tsv.gz; done | cut -f 3,10 | sed -E -e's/^([0-9]+)       ([ACGTN]+)$/>\1Z\2/' | tr "Z" "\n" > cat.fa    

awk 또는 Perl을 사용하는 아래 두 솔루션 모두 완벽하게 작동합니다. 화이트리스트에 있는 ID가 순서가 아니더라도 순서대로 출력됩니다. Perl 솔루션은 탭으로 구분된 줄을 인쇄하는 반면 awk는 공백으로 구분된 줄을 인쇄합니다.

답변1

perl -F'\t+' -lane '
   @ARGV and $h{$F[0]}++,next;
   print ">", join("\t", @F[2..5,-4..-1]), $\, $F[9] if exists $h{$F[2]};
' whitelist.txt batch_1.catalog.tags.tsv

파일이 탭으로 구분되어 있다고 가정합니다.

파일에 Windows 또는 Mac 줄 끝이 있을 수 있는 경우 먼저 dos2unix와 같은 유틸리티를 통해 Unix 줄 끝("\n")으로 변환하는 것이 현명합니다. 왜냐하면 제공된 코드가 이와 같은 이유로 OP 측에서 작동하지 않는 경우가 많기 때문입니다.

작동 원리

  • Perl첫 번째 인수(이 경우 whitelight.txt@ARGV) 가 처리 되면 batch_1.catalog.tsv파일이 저장됩니다. 즉, @ARGV = 1 => @ARGV는 부울 컨텍스트에서 TRUE로 평가됩니다.
  • @ARGV and $h{$F[0]}++,next이는 다음과 같이 설명할 수 있습니다. 백색광 파일을 처리하면 $F[0]파일의 첫 번째 필드( )가 해시에 추가된 %h후 즉시 다음 줄로 이동합니다.
  • @ARGV에는 당시 아무 것도 포함되어 있지 않으므로 이 아래 줄은 TSV 파일을 처리하므로 개수는 0입니다.
  • $F[2]세 번째 필드가 해시의 키가 되는 TSV 파일 레코드만 표준 출력으로 이동해야 합니다 %h.
  • TSV 레코드를 인쇄하기로 결정하면 인쇄 형식은 다음과 같습니다. (참고: OFS기본 인쇄 형식은 입니다 NULL.)
  • ">", $F[2]즉 세 번째 필드 앞에는>
  • 필드 4,5,6 => @F[3..5]TAB으로 분리되고 연결됩니다.
  • 마지막 4개 필드 => @F[-4..-1]TAB으로 구분되어 연결됩니다.
  • 10번째 필드 앞에는 == 옵션으로 인해 $F[9]제공되는 개행 문자가 옵니다 .$\ORS\nPerl-l

답변2

해결책:

파일에서 테스트 조각을 가정합니다 batch_1.catalog.tags.tsv.

0   1   6   gi|586799556|ref|NW_006530744.1|    141 +   consensus   0   1_33,14_43  CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC    0   0   0   0
1   2   7   hi|686711556|ref|NW_006530744.2|    141 +   consensus   0   1_33,14_43  CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC    1   1   0   1
2   2   8   hi|686711556|ref|NW_006530744.2|    141 +   consensus   0   1_33,14_43  CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC    1   1   1   1
3   3   9   th|776711556|ref|NW_006530744.2|    141 +   consensus   1   1_33,14_43  CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC    1   0   1   1

whitelight.txt그리고 파일의 테스트 조각은 다음과 같습니다.

6
7
9

주문하다:

awk 'NR==FNR{ a[$0]++; next }{ if ($3 in a) { 
     $0=">"$3 FS $4 FS $5 FS $6 FS $11 FS $12 FS $13 FS $14 RS $10; print}}' whitelist.txt batch_1.catalog.tags.tsv > cat.fa

최종 cat.fa콘텐츠:

>6 gi|586799556|ref|NW_006530744.1| 141 + 0 0 0 0
CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC
>7 hi|686711556|ref|NW_006530744.2| 141 + 1 1 0 1
CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC
>9 th|776711556|ref|NW_006530744.2| 141 + 1 0 1 1
CGGGCGGTGGTGGCGCACGCCTTTAATCCCAGCACTTGGGAGGCAGAGGCAGGTGGATCTTTGTGAGTTCGAGGCCAGCCTGGGCTACCAAGTGAGCTCC

세부 사항:

NR==FNR- 첫 번째 파일에 대해 작업을 수행합니다.whitelight.txt

a[$0]++;- whitelight.txt파일에서 숫자를 누적

if ($3 in a)- 두 번째 파일의 세 번째 열 값이 누적 개수와 일치하면 작업을 허용합니다.

RS- awk의 레코드 구분 기호, 기본값은 개행입니다.

관련 정보