"uniq --unique"가 모든 중복 행을 제거하지 않는 이유는 무엇입니까?

"uniq --unique"가 모든 중복 행을 제거하지 않는 이유는 무엇입니까?

달리기

printf "lol\nlol\nfoo\n\n\n\n\nbar\nlol\nlol\nfoo\nlol\nfoo" | uniq --unique

인쇄

foo
bar
foo
lol
foo

foo세 번 인쇄되었습니까? uniq --unique삭제하면 안되는 것인가요 ?

lol또한 모든 중복 항목이 제거된 것처럼 보인다는 점도 주목할 가치가 있습니다 . 왜?중복된 항목은 제거되지만부자반복하다?

답변1

uniqman uniq입력을 제거하려면 입력(from)을 정렬해야 합니다.모두중복된 행:

설명하다

INPUT(또는 표준 입력)에서 인접한 일치하는 라인을 필터링하고 OUTPUT(또는 표준 출력)에 씁니다.

위에서 볼 수 있듯이 필터링만 수행됩니다.가까운일치하는 라인. 이것이 lols가 제거된 이유입니다. 따라서 데이터는 다음으로 전달되기 전에 정렬됩니다 uniq.

$ printf "lol\nlol\nfoo\n\n\n\n\nbar\nlol\nlol\nfoo\nlol\nfoo" | sort | uniq 

bar
foo
lol

또는 GNU를 사용하여 sort다음을 건너뜁니다 uniq.

$ printf "lol\nlol\nfoo\n\n\n\n\nbar\nlol\nlol\nfoo\nlol\nfoo" | sort --unique

bar
foo
lol

마지막으로, 행의 여러 항목을 완전히 제거하려면(기본 동작인 복사본을 유지하는 대신) uniq -u또는 --unique질문에 표시된 대로 사용하세요.

$ printf "lol\nlol\nfoo\n\n\n\n\nbar\nlol\nlol\nfoo\nlol\nfoo" | sort | uniq -u
bar

그러나 모든 경우에 정렬이 필요합니다.

답변2

foo왜 아직도 목록에 있는지 궁금하시죠 ? uniq인접한 중복 행만 삭제하고 인접한 중복 행을 단일 행으로 "압착"합니다. GNU를 사용하면 -u(또는 --uniqueGNU를 사용하면 uniq) 인접한 중복 행이 있는 행도 제거됩니다.

귀하의 예에서는 세 행 중 어느 것도 foo다른 행과 인접 하지 않습니다 foo. 그것이 그들이 수출되는 이유입니다.

삭제된 행은 lol내용이 있는 다른 행에 인접해 있으므로 삭제됩니다 lol. 이러한 의미에서 마지막 lol행은 반복되지 않으므로 유지됩니다.

관련 정보