特定の列に基づいて1行を2行に分割

特定の列に基づいて1行を2行に分割

.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.txt3番目の列番号(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\nPerl-l

おすすめ記事