.tsv
以下を含むファイル(batch_1.catalog.tags.tsv
)があります。1,965,056行14列。そのうちのいくつかを2行に分けたい。
最初の行:より大きい記号(>)で始まり、その後に14列のうち8列が続きます。
2行目: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
以下は、3番目の列で指定されたファイルの6行目の例です。
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
しかし、3番目の列番号が他のテキストファイル(whitelist.txt)の番号と一致するtsvファイル(batch_1.catalog.tags.tsv)の行に対してのみこれを実行したいと思います。
上記の例では、whitelist.txt
3番目の列番号(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]
3番目のフィールドがハッシュのキーとなるTSVファイルレコードのみを標準出力に移動する必要があります%h
。- TSV レコードを印刷する場合、印刷形式は次のようになります。 (注:
OFS
デフォルトの印刷形式はですNULL
。) ">"
つまり、$F[2]
3番目のフィールドの前に>
- フィールド 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)
- 2 番目のファイルの 3 番目の列の値が累積数と一致する場合、操作を許可します。
RS
- awkのレコード区切り記号、デフォルトは改行です。