두 명령으로 생성된 출력에 공통된 줄 제거

두 명령으로 생성된 출력에 공통된 줄 제거

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

$ ./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

괄호는 둘 다의 stdout을 가져오고 ./c1명령 ./c2의 stdin으로 가져옵니다 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'

관련 정보