탭으로 구분된 파일의 쉼표로 구분된 목록을 별도의 줄로 확장합니다.

탭으로 구분된 파일의 쉼표로 구분된 목록을 별도의 줄로 확장합니다.

나는 매우 비슷한 문제가 있습니다이 문제, 하지만 내 질문에 대한 답변을 조정하는 방법을 모르겠습니다.

두 번째 열에 쉼표로 구분된 목록이 포함된 탭으로 구분된 파일이 있습니다. 예를 들면 다음과 같습니다.

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}'

그런데 문제를 해결하려면 어떤 부분을 바꿔야 할지 모르겠어요!

도움을 주셔서 감사합니다.

답변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 스칼라는 처음 두 필드를 보유하고 /c 수정자로 인해 중지된 곳에서 while 루프의 검색이 시작됩니다.

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

관련 정보