Text-Processing

將製表符分隔文件中的逗號分隔列表擴展為單獨的行

  • April 14, 2021

我有一個與這個問題非常相似的問題,但不知道如何使答案適應我自己的問題。

我有一個 tab-sep 文件,第二列包含逗號列表,例如:

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

第三列中有可變數量的術語。我需要一個單獨的行與它關聯的第一列和第二列。

如果有任何幫助,上述問題的出發點是:

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

但我不知道需要更改哪些位才能解決我的問題!

非常感謝您的幫助。

這個 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

如果您不確定是否有實際的製表符:

  • awk:FS = ",|[[:blank:]]+"
  • perl:-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 慢得多。

引用自:https://unix.stackexchange.com/questions/644905