
저는 아직 프로그래밍을 배우고 있으며 많은 것을 시도했지만 올바른 형식을 얻을 수 없습니다. 나는탭으로 구분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
FILE FORMAT(다른 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개가 있어야 합니다. , 열 1(이 특정 파일의 경우)에 대한 반복이 많기 때문입니다.
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 솔루션:
$ 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