
예를 들어, 일부 텍스트를 반환하는 두 가지 명령이 있습니다. 예를 들어:
$ ./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
에서 :comm
GNU 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'