나는 매우 비슷한 문제가 있습니다이 문제, 하지만 내 질문에 대한 답변을 조정하는 방법을 모르겠습니다.
두 번째 열에 쉼표로 구분된 목록이 포함된 탭으로 구분된 파일이 있습니다. 예를 들면 다음과 같습니다.
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