タブ区切りファイルのカンマ区切りリストを別々の行に展開します。

タブ区切りファイルのカンマ区切りリストを別々の行に展開します。

私は非常に似た問題がありますこの問題しかし、私の質問に対する答えを調整する方法がわかりません。

2番目の列には、カンマ区切りリストを含むタブ区切りファイルがあります。たとえば、次のようになります。

TRINITY_DN1_c0_g1   DN1_c0_g1   GO:0000166,GO:0003674,GO:0005488,GO:0005515,GO:0005524,GO:0005575
TRINITY_DN1_c0_g3   DN1_c0_g3   GO:0005829,GO:0006457,GO:0006458,GO:0006950,GO:0008134
TRINITY_DN10_c0_g1  DN10_c0_g1  GO:0050896,GO:0051082,GO:0051084,GO:0051085

私はこれをしたい:

TRINITY_DN1_c0_g1   DN1_c0_g1   GO:0000166
TRINITY_DN1_c0_g1   DN1_c0_g1   GO:0003674
TRINITY_DN1_c0_g1   DN1_c0_g1   GO:0005488
TRINITY_DN1_c0_g1   DN1_c0_g1   GO:0005515
TRINITY_DN1_c0_g1   DN1_c0_g1   GO:0005524
TRINITY_DN1_c0_g1   DN1_c0_g1   GO:0005575
TRINITY_DN1_c0_g3   DN1_c0_g3   GO:0005829
TRINITY_DN1_c0_g3   DN1_c0_g3   GO:0006457
TRINITY_DN1_c0_g3   DN1_c0_g3   GO:0006458
TRINITY_DN1_c0_g3   DN1_c0_g3   GO:0006950
TRINITY_DN1_c0_g3   DN1_c0_g3   GO:0008134
TRINITY_DN10_c0_g1  DN10_c0_g1  GO:0050896
TRINITY_DN10_c0_g1  DN10_c0_g1  GO:0051082
TRINITY_DN10_c0_g1  DN10_c0_g1  GO:0051084
TRINITY_DN10_c0_g1  DN10_c0_g1  GO:0051085

3番目の列の用語の数は可変です。接続された最初の列と2番目の列にはそれぞれ1行が必要です。

役立つ場合は、上記の質問の出発点は次のとおりです。

perl -lne 'if(/^(.*?: )(.*?)(\W*)$/){print"$1$_$3"for split/, /,$2}'

ところで、問題を解決するにはどの部分を変えなければならないのか分からない!

助けてくれてありがとう。

答え1

この awk コマンドは非常に読みやすいです。

awk '
  BEGIN {FS = "[,\t]"; OFS = "\t"}
  {for (i=3; i<=NF; i++) print $1, $2, $i}
' file

Perlでは、次のようになります。

perl -F'[,\t]' -lane 'print join "\t", @F[0,1], $F[$_] for 2..$#F' file
# or
perl -F'[,\t]' -slane 'print @F[0,1], $F[$_] for 2..$#F' -- -,=$'\t' file

実際のタブ文字があるかどうかわからない場合:

  • 奇妙な:FS = ",|[[:blank:]]+"
  • 真珠:-F',|\s+'

楽しみとしてbash

while IFS= read -r line; do
    prefix=${line%%GO:*}
    IFS=, read -ra gos <<< "${line#$prefix}"
    for go in "${gos[@]}"; do echo "$prefix$go"; done
done < file

このバージョンはスペースやタブを気にしませんが、たくさんPerlやawkより遅いです。

答え2

スイッチを使用して、-a各行をスペースの @F 配列に分割します。

perl -lane 'print join "\t", @F[0, 1], $_ for split /,/, $F[2]'

答え3

ここで別のオプションnest --explodeミラー

mlr --nidx --fs tab nest --explode --values --across-records --nested-fs ',' -f 3 file

または、省略形nest指定子を使用します。

mlr --nidx --fs tab nest --evar ',' -f 3 file

答え4

使用GNU sedこれには [\n\t] 正規表現機能があり、次のように実行できます。

sed -n '
  y/,/\n/
  :a
      P; s/\t[^\n\t]*\n/\t/
  ta
'  file

使用できる真珠返品

perl -F'(\t)' -pale '$"="";
  $_ = pop(@F) =~ tr/,/\n/r =~ s/^/@F/mgr;
' file

一つの方法は真珠ここに表示されます。 $a スカラーは最初の 2 つのフィールドを保持し、/c 修飾子によって停止した場所で while ループの検索が開始されます。

perl -lne '
  my($a) = /^((?:.*?\t){2})/gc;
  print $a, $1 while /\G([^,]+)(?:,|$)/g;
' file

関連情報