열 값을 기준으로 고유한 행을 얻는 방법

열 값을 기준으로 고유한 행을 얻는 방법

다음을 입력:

A 13
A 12
B 17
C 33
D 344
C 24
A 5
C 99

첫 번째 열만 있는 행을 가져오고 싶습니다.

B 17
D 344

한 가지 솔루션이면 awk좋지만 다른 솔루션도 허용됩니다.

답변1

순서를 섞는 것이 괜찮다면

sort <file> | uniq -uw 1

자세한 내용 은 리소스를 참조하세요 man uniq. 중요한 부분은 다음과 같습니다.

   -u, --unique
          only print unique lines
   -w, --check-chars=N
          compare no more than N characters in lines

답변2

그리고 awk:

awk 'NR==FNR { a[$1]++ } NR!=FNR && a[$1]==1' file file

(파일 이름이 두 번 전달됩니다.)

편집하다:파일이 원본인 경우 stdin임시 복사본이 필요합니다. 이 같은:

tmp="$( mktemp -t "${0##*/}"_"$$"_.XXXXXXXX )" && \
    trap 'rm -f "$tmp"' 0 HUP INT QUIT TERM || exit 1
... | tee "$tmp" | awk '...' - "$tmp"

답변3

당신이 할 의향이 있다면

awk '
    $1 in ARR{
        ARR[$1] = RS;
        next;
    }
    {
        ARR[$1] = $0;
    }
    END{
        for(i in ARR)
            if(ARR[i] != RS)
                print ARR[i];
    }
    ' file

스크립트는 첫 번째 필드를 인덱스로, 전체 행을 값으로 사용하여 행을 ARR 배열에 넣습니다. 배열에 이미 동일한 인덱스가 있는 경우 값을 "\n"(개행) 기호로 변경합니다. 파일 끝에서 값이 «\n»과 같지 않은 배열 요소를 인쇄합니다.
awk의 RS변수는 newline기본적으로 동일합니다.

아니면 이렇게 할 수도 있어요sed

sort file |
sed '
    :a;
    $!N;
    s/\(\S\+\s\).*\n\1.*/\1\a/;
    ta;
    /\a/P;
    D;
    '

답변4

perl -lane '
   exists $h{$F[0]} and undef $h{$F[0]},next;

   ( $h{$F[0]}, $h[@h] ) = ( $_, $F[0] );

   END{ print $h{$_} for grep { defined $h{$_} } @h }
' yourfile

코드가 하는 일은 첫 번째 필드가 이전에 발견되었는지 확인하는 것입니다. 그런 다음 해당 이름의 키가 해시에 존재할 것이므로 undef어쨌든 배열을 구축할 필요가 없기 때문에 해당 특정 키의 값을 계속 계산합니다. 결국 폐기될 것입니다. 대신, 우리는 더 작은 기억 각인을 통해 동일한 정보를 전달합니다.

첫 번째 필드가 처음 표시되면 %h해시를 현재 행으로 채우고 동시에 @h해당 키로 배열을 추가합니다. 키가 발견되는 순서를 유지하기 위해 이 단계를 수행합니다. 주문이 마음에 들지 않으면 이 단계를 완전히 취소할 수 있습니다.

마지막으로 모든 입력이 다이제스트되면 마지막 END블록에서 배열 요소를 반복하여 정의된 값을 @h해시하는 요소만 찾습니다 . 가치는 두 번 이상 표시된다는 점을 %h기억하세요 .undef

관련 정보