열 1을 기준으로 동일한 파일의 여러 줄 병합

열 1을 기준으로 동일한 파일의 여러 줄 병합

저는 아직 프로그래밍을 배우고 있으며 많은 것을 시도했지만 올바른 형식을 얻을 수 없습니다. 나는탭으로 구분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

관련 정보