두 명령으로 생성된 출력에 공통된 줄을 제거합니다.

두 명령으로 생성된 출력에 공통된 줄을 제거합니다.

일부 텍스트를 반환하는 두 가지 명령이 있다고 가정해 보겠습니다. 예를 들어:

$ ./c1
/usr/bin/foo
/usr/bin/bar
/usr/bin/baz
$ ./c2
/usr/bin/foo
/usr/bin/qux
/usr/bin/buzz
/usr/bin/bar

중복된 행을 제거하고 싶습니다. 즉, 출력은 다음과 같습니다(순서는 중요하지 않습니다).

/usr/bin/baz
/usr/bin/qux
/usr/bin/buzz

어떻게 해야 하나요?

답변1

상당히 간단한 파이프라인이 트릭을 수행해야 합니다.

(./c1; ./c2) | sort -u

대괄호는 두 가지 모두의 표준 출력을 얻고 ./c1명령 ./c2의 표준 입력으로 이동합니다 sort. 이 옵션은 -u일치하는 각 줄 집합 중 하나만 인쇄합니다.

단순화에 대해 알아주신 John WH Smith와 통찰력을 주신 Bakuriu에게 감사드립니다.

답변2

에서 :commGNU coreutils

$ comm -3 <(sort -u <(./c1)) <(sort -u <(./c2)) | tr -d '\t'
/usr/bin/baz
/usr/bin/buzz
/usr/bin/qux

에서 man comm:

Compare sorted files FILE1 and FILE2 line by line.

       With  no  options,  produce  three-column  output.  Column one contains
       lines unique to FILE1, column two contains lines unique to  FILE2,  and
       column three contains lines common to both files.

       -1     suppress column 1 (lines unique to FILE1)

       -2     suppress column 2 (lines unique to FILE2)

       -3     suppress column 3 (lines that appear in both files)

답변3

awk-pipe는 첫 번째 입력 행만 전달합니다.

( ./c1 ; ./c2 ) | awk '!u[$0]++'

정렬하는 데 시간이 걸리지 않지만 표시된 행을 기억해야 합니다. 따라서 큰 입력의 경우 더 나을 수 sort있습니다 uniq...

답변4

sed텍스트를 구문 분석하고 중복된 줄을 제거하려면 이 기능을 활용하는 것이 좋습니다 . 따라서 첫 번째 명령은 중복된 줄을 유지합니다. sed '$!N; /^\(.*\)\n\1$/!P; D'

두 번째 명령은 중복을 제거합니다 sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'

관련 정보