.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
\n
Perl
-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의 레코드 구분 기호, 기본값은 개행입니다.