저는 아직 프로그래밍을 배우는 중이고 많은 것을 시도했지만 형식을 올바르게 지정할 수 없습니다. 나는탭으로 구분됨파일에는 17개의 열과 많은(약 50,000개) 행이 있습니다. 파일은 첫 번째 열을 기준으로 정렬됩니다. 동일한 첫 번째 열(A)이 있는 행을 병합하고 싶지만 다른 16개 열은 모두 다르며 모든 정보를 한 행, 바람직하게는 동일한 열에 유지하고 싶습니다.세미콜론 ;그들 사이의 구분자로. 출력 파일에서 탭 문자를 구분 기호로 유지하고 싶습니다. 답변해 주셔서 대단히 감사합니다. 제가 어디에서 잘못되었는지 설명해 주시면 더 좋을 것 같습니다. :)
내가 지금까지 시도한 것 :
awk -F'\t' 'NF>1{a[$1] = a[$1]";"$2}END{for(i in a){print i""a[i]}}' filename.txt
perl -F',' -anle 'next if /^$/;$h{$F[0]} = $h{$F[0]}.", ".$F[1];
END{print $_,$h{$_},"\n" for sort keys %h}' filename.txt
파일 형식(나머지 15개 열은 B열과 형식이 동일함)
A B C
123 fvv ggg
123 kjf ggg
123 ccd att
567 abc gst
567 abc hgt
879 ttt tyt
내가 원하는 출력(17개 열이 모두 필요하고, 2-16열에는 B열과 C열과 동일한 출력이 필요합니다). B의 모든 케이스는 B 아래에 있어야 하고, C의 모든 케이스는 C 아래에 있어야 하며, D의 모든 케이스는 D 아래에 있어야 합니다. 따라서 출력에는 입력과 동일한 17개의 열이 있으며, 첫 번째 열(이 특정 파일의 경우)에 많은 반복이 있으므로 이제 50,000개의 행 대신 약 20,000개의 행이 있어야 합니다.
A B C
123 fvv;kjf;ccd ggg;ggg;att
567 abc;abc gst;hgt
879 ttt lll
답변1
awk '{
if(NR!=1){a[$1]=$2";"a[$1]}
else print $0}
END{
n = asorti(a, b);
for (n in b) {
print b[n],a[b[n]]
}
}'
답변2
펄 솔루션:
$ perl -F"\t" -anle 'if($.==1){print; next} push @{$k{$F[0]}},@F[1..$#F];
END{print "$_\t" . join(";",@{$k{$_}}) for sort keys(%k)}' file
A B
123 fvv;kjf;ccd
567 abc;abc
879 ttt
이는 여러 필드에 적용될 수 있습니다. 그러나 상당한 양의 콘텐츠를 메모리에 로드해야 하므로 파일이 큰 경우 문제가 될 수 있습니다.
어디서 잘못되었는지에 관해서는 실제로 무슨 일이 일어났는지 설명하지 않으면 알 수 없습니다. 하지만 제 머리로는 다음과 같은 이유로 Perl 시도가 실패했습니다.
- 입력에 탭이 있는 경우
-F,
이를 사용하여 필드 구분 기호를 쉼표로 설정합니다. -l
및 을(를) 사용하고 있습니다print "foo\n"
. 각 인쇄 호출에 개행 문자가 추가 되었으므로-l
여러 개의 빈 줄이 생깁니다.- 추가를 사용하고 있으므로
$h{$F[0]}.", ".$F[1];
처음 실행하고 정의되지 않은 경우 저장된 값의 시작 부분에 추가 값을 추가$h{$F[0]}
하게 됩니다 .,
- 두 번째 필드만 보고 다른 모든 필드는 무시합니다.
awk
마찬가지로 다음과 같은 이유로 귀하의 의지가 실패하게 됩니다.
- 인쇄 중입니다
foo""bar
. 이렇게 하면 각 필드 사이에 공백 없이 출력이 연결됩니다. 탭으로 구분된 출력을 원print foo,bar
하고 원합니다OFS="\t"
. - 두 번째 필드만 보고 다른 모든 필드는 무시합니다.
답변3
죄송하지만 문제는 이렇습니다.
awk 'BEGIN{FS="\t"} {for(i=2; i<=NF; i++) { if (!a[$1]) a[$1]=$1FS$i ;else a[$1]=a[$1]";"$i};if ($1 != old) b[j++] = a[old];old=$1 } END{for (i=0; i<j; i++) print b[i] }' 1
123 fvv ;kjf;ccd
567 abc;abc
879 ttt
답변4
awk '
function p(n,A){
s = n
for(i=2;i<=NF;i++){
s = s "\t" A[i]
A[i] = $i
}
if(n)
print s
}
NR==1{
print
next
}
$1==n{
for(i=2;i<=NR;i++)
A[i] = A[i] ";" $i
next
}
{
p(n,A)
n = $1
}
END{
p(n,A)
}
' file