uniq --unique가있을 정도로 어떻게 uniq이 고유하지 않습니까?


35

pastebin 의 임의 파일에 대한 명령은 다음과 같습니다 .

wget -qO - http://pastebin.com/0cSPs9LR | wc -l
350
wget -qO - http://pastebin.com/0cSPs9LR | sort -u | wc -l
287
wget -qO - http://pastebin.com/0cSPs9LR | sort | uniq | wc -l
287
wget -qO - http://pastebin.com/0cSPs9LR | sort | uniq -u | wc -l
258

매뉴얼 페이지는 -u플래그가 수행하는 작업 에 대해 명확하지 않습니다 . 어떤 충고?


4
정렬 해보기 | 유니크 -d | wc -l 및 차이점을 발견 할 수 있습니다. :)
stoeff 2016 년

답변:


42

짧은 버전 :

  • uniq가 없으면 출력의-u 모든 줄 고유 하게 만듭니다 .
  • uniq -u입력에서 모든 고유 한 행만 인쇄합니다 .

약간 긴 버전 :

uniq행이 복제 된 파일을 처리하기위한 것이며 해당 행이 입력에 연속적으로 나타나는 경우에만 해당됩니다. 따라서 고유 한 행은 즉시 복제되지 않는 행입니다.

( uniq매우 제한된 단기 기억을 가지고, 라인 입력에 앞서 출연 여부는 바로 이전 행이었다 않는 한, 기억하지 않습니다 -이 왜 uniq자주와 결합한다 sort.)

중복 된 행이 발견되면 arg uniq없이 해당 행의 사본 하나를-u 인쇄합니다 . (출력의 모든 줄을 고유 하게 만듭니다 ).

-u인수를 사용하면 해당 행의 사본을 0으로 인쇄 합니다. 중복 된 사본은 출력에서 ​​생략됩니다.


1
정렬이 필요없는 옵션이 있었으면 좋겠다. 그러나 전체 파일을 메모리에 보관해야합니다 (또는 소스가 일반 파일 인 경우 해시 및 오프셋을 사용하여 많은 부기를 유지해야 함)
Random832

3
@ Random832 : 그리고 어떤 듀프를 유지할 것인지 (먼저, 마지막, 다른 것, 구성 가능)를 결정해야하며, 그 결정은 전 세계적으로 알고리즘에 영향을 미칩니다. 혼전.
Steve Jessop

1
@ Random832 : 입력 할 문자 수에 불과하면 sort -u대신 대신 사용할 수 있습니다 sort | uniq.
oliver

@oliver 가끔씩 줄을 바꾸지 않고 줄의 첫 번째 인스턴스를 유지하고 스크립트를 작성하는 기능을 원했습니다.
Random832

1
@ hvd : 버전 uniq이 정규화 및 데이터 정렬을 수행하는 경우 가능합니다. 그러나 그때조차도 로컬 고려 사항 일뿐입니다. 정렬 된 출력에서 ​​라인이 표시되는 위치를 알고 있으며 인접한 여러 라인 중 유지할 라인을 선택해야합니다. 입력이 정렬되지 않은 경우 결정은 uniqifying의 전체 작업에 영향을 미칩니다. 예를 들어 마지막 복제본을 유지하려는 경우 입력의 마지막 줄을 읽을 때까지 아무것도 출력 할 수 없습니다 ...
Steve Jessop 2016 년

53

uniqwith -u는 중복 된 행을 건너 뜁니다. 그러므로:

$ printf "%s\n" 1 1 2 3 | uniq
1
2
3
$ printf "%s\n" 1 1 2 3 | uniq -u
2
3

일반적으로 uniq줄을 최대 한 번 인쇄합니다 (정렬 된 입력을 가정). 이 옵션은 실제로 고유 한 행을 인쇄합니다 (다시 나타나지 않음).


11
즉, 모든 고유 한 선을 인쇄하는 반면 모든 고유 한 선을 인쇄 uniq하므로이라고 할 수 있습니다 . distinctuniq -u
Steve Jessop

일부 로케일에서 GNU와 고유 한 것은 아닙니다 uniq.
cuonglm

내가 허용 대답을 여러 번 읽게해야하지만 싱크대하지 않았다 귀하의 예 및 단락을 그것은 매우 분명 :) (다시 가서 허용 대답을 다시 읽고, 나도 그 얻을) 한 후에.
Madivad

18

uniq POSIX 사양 에 명확하게 설명되어 있습니다.

-u
    Suppress the writing of lines that are repeated in the input.

-u옵션은 uniq반복되는 줄을 인쇄하지 않습니다.

대부분의 uniq구현에서는 바이트 비교를 사용했지만 GNU uniq는 데이터 정렬 순서를 사용하여 중복 된 행을 필터링했습니다. 따라서 로케일과 같은 일부 로케일에서 잘못된 결과를 생성 할 수 있습니다 en_US.UTF-8.

$ printf '%b\n' '\U2460' '\U2461' | uniq
①

그리고 -u당신에게 줄을주지 않았습니다 :

$ printf '%b\n' '\U2460' '\U2461' | uniq -u
<blank>

따라서 C바이트 비교를 받으려면 로케일을 설정해야합니다 .

$ printf '%b\n' '\U2460' '\U2461' | LC_ALL=C uniq
①
②

3
여기서 잘못된uniq은 POSIX의 의도는 (2)와 같은 sort -u①로 잘못 정렬 된 로케일 보다 strcoll () 비교 대신 바이트 비교를 수행해야한다는 점 입니다. 적어도 GNU는와 uniq일치합니다 sort -u.
Stéphane Chazelas

@ StéphaneChazelas-사양의 어느 부분이 명백한가?
mikeserv 2016 년

에 대해 uniq나에게 매우 분명 아니라고, strcoll에 반대하지만, 같은 memcmp는 / STRCMP을 수행하는 데 필요한 제프하는 것이라고 . ①과 ②가 같은 GNU 로케일에 대해, 그것들이 똑같이 정렬해야 할 이유가 없기 때문에 분명히 버그입니다. POSIX에서 허용하지만 약간의 변화가 있습니다.
Stéphane Chazelas 7

8

표준:

echo "a b a b c c c" | tr ' ' '\n'
a
b
a
b
c
c
c

uniq : 두 개의 반복되는 줄이 없음

echo "a b a b c c c" | tr ' ' '\n' | uniq
a
b
a
b
c

정렬

echo "a b a b c c c" | tr ' ' '\n' | sort
a
a
b
b
c
c
c

sort -u : 반복되는 두 줄이 없습니다.

echo "a b a b c c c" | tr ' ' '\n' | sort -u
a
b
c

정렬 / 유니크 : 모두 구별

echo "a b a b c c c" | tr ' ' '\n' | sort | uniq
a
b
c

별개의 사건을 센다

echo "a b a b c c c" | tr ' ' '\n' | sort | uniq -c
2 a
2 b
3 c

반복되지 않는 행만 (먼저 정렬되지 않음)

echo "a b a b c c c" | tr ' ' '\n' | uniq -u
a
b
a
b

반복되지 않은 행만 (정렬 후)

echo "a b a b c c c Z" | tr ' ' '\n' | sort | uniq -u
Z

uniq -d : 각 그룹마다 하나씩 중복 행만 인쇄

echo "a b a b c c c" | tr ' ' '\n' | uniq -d
c

.. 계산

echo "a b a b c c c" | tr ' ' '\n' | uniq -dc
3 c

좋은 명확한 예 :)
Madivad
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.