파일에서 고유하지 않은 모든 줄을 찾으려면 uniq를 사용하려고 합니다. 고유하지 않다는 것은 이전 행에서 이미 본 모든 행을 의미합니다. 내 생각에 "-D" 옵션은 다음과 같은 역할을 합니다.
-D print all duplicate lines
그러나 반복되는 줄을 인쇄하는 대신모두여러 줄이 있을 때. 행의 두 번째 및 후속 사본만 인쇄하고 싶습니다.
어떻게 해야 하나요?
답변1
소문자 -d 옵션의 GNU 버전이 필요합니다.
# printf "a\na\na\nb\nb\nc\n" | uniq -d
a
b
답변2
GNU 또는 ast-open을 사용하여 구현됨 uniq
:
uniq -D -u < input
( -D
자체는 비표준), 그러나 이것은 첫 번째가 아니라 제거하는 마지막 중복이라는 점에 유의하십시오( -i
, 또는 도 사용하면 -w
차이가 발생함 -f
).
이식 가능한 경우 언제든지 다음을 사용할 수 있습니다 awk
.
awk 'NR > 1 && $0 "" == previous ""; {previous = $0}' < input
(is와 연결하면 ""
피연산자가 숫자처럼 보이더라도 문자열 비교가 강제됩니다.)
처음 9자만 비교합니다(이것은 -w
또한 GNU 확장이며 (현재) 문자가 아닌 바이트에서 작동한다는 점에 유의하십시오(문서에 그렇게 나와 있지만)).
awk '{current = substr($0, 1, 9)}
NR > 1 && current == previous
{previous = current}' < input
""
(이 경우 substr()
문자열이 반환되므로 연결이 필요하지 않습니다.)
UTF-8 로케일에서 출력 시
printf '%s\n' StéphaneChazelas StéphaneUNIX StéphaneUnix
StéphaneUnix
예상대로 while uniq -w9 -D -u
(GNU 사용 uniq
) 을 제공 StéphaneChazelas
하고 -is StéphaneUNIX
로 8자를 제공 Stéphane
하지만 UTF-8에서는 9바이트를 제공하는 반면 ast-open uniq
은 StéphaneUNIX( awk
첫 번째 항목 건너뛰기, uniq
마지막 항목 한 번 제거)만 제공합니다.
를 사용하면 awk
다음 항목에 인접하지 않더라도 모든 중복 행을 보고할 수도 있습니다.
awk 'seen[$0]++' < input
(메모리의 모든 고유 행을 해시 테이블에 저장합니다.)
또는 처음 9자만 고려하십시오.
awk 'seen[substr($0, 1, 9)]++' < input
답변3
해결책은 uniq를 사용한 -c
다음 원하는 것을 제거하는 것 입니다.
e444$ ( echo a ; echo a ; echo b ; echo d ; echo d ; echo e ) | uniq -c
2 a
1 b
2 d
1 e
a
반복 d
되어 이중 b
으로e
e444$ ( echo a ; echo a ; echo b ; echo d ; echo d ; echo e ) | uniq -c \
| sed -E '/^ *1 .$/d;s/^ *[0-9]+ //'
표현 설명 sed
:
/^ *1 .$/d
모든 고유 행을 삭제합니다
s/^ *[0-9]+ //
카운터가 삭제됩니다