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