“ sort -u ”와 “ sort | uniq ”?

정렬되고 고유 한 목록을 가져와야하는 사람을 볼 때마다 항상 sort | uniq로 연결됩니다. 나는 누군가가 대신 sort -u를 사용하는 예를 본 적이 없습니다. 왜 안됩니까? 차이점은 무엇이며 정렬 할 때 고유 플래그보다 uniq를 사용하는 것이 더 좋은 이유는 무엇입니까?

댓글

답변

sort | uniq가 이며 더 넓은 범위의 시스템과 호환됩니다. 거의 모든 최신 시스템이 -u를 지원하지만 POSIX입니다. 대부분 후퇴입니다. sort -u가 존재하지 않았던 시대까지 (그리고 사람들이 알고있는 방식이 계속 작동하면 방법을 변경하지 않는 경향이 있습니다. ifconfig vs. ip 채택).

파일 내에서 중복을 제거하려면 정렬이 필요하기 때문에 (적어도 표준에서는 case)이며 매우 일반적인 사용 사례입니다. 또한 두 작업을 동시에 수행 할 수 있기 때문에 내부적으로 더 빠릅니다 (그리고 uniqsort). 특히 파일이 큰 경우 sort -u는 데이터를 정렬하는 데 더 적은 수의 중간 파일을 사용합니다.

내 시스템에서 다음과 같은 결과를 지속적으로 얻습니다.

$ dd if=/dev/urandom of=/dev/shm/file bs=1M count=100 100+0 records in 100+0 records out 104857600 bytes (105 MB) copied, 8.95208 s, 11.7 MB/s $ time sort -u /dev/shm/file >/dev/null real 0m0.500s user 0m0.767s sys 0m0.167s $ time sort /dev/shm/file | uniq >/dev/null real 0m0.772s user 0m1.137s sys 0m0.273s 

또한 sort의 반환 코드를 마스킹하지 않습니다. 중요 할 수 있습니다 (최신 셸에는 bash “의 $PIPESTATUS 배열과 같이이를 얻는 방법이 있지만 이것은 그렇지 않습니다. 항상 참).

댓글

  • sort | uniq를 사용하는 경향이 있습니다. 저는 ' 실제로 uniq -c에 배관하고 있습니다.
  • sort -u는 1979 년경 UNIX 7 판의 일부였습니다. sort 버전 -u에 대한 지원은 실제로 구식이거나 POSIX '의 법정 표준 이전에 사실상 표준에 대한 관심없이 작성되었습니다. 2010 년부터 Stack Overflow Sort & uniq in Linux shell 도 참조하세요.
  • +1 이유 ip. ' 2016 년과 2013 년이 게시물이지만 지금은 ip 명령에 대해서만 알고 있습니다.
  • +1 " 9 회 초과 10 I ' 실제로 uniq -c " (그리고 한 번 더 sort -nr | head에 배관). Vim에 :sort u 명령이 있다는 것을 알았을 때 Vim의 sort | uniq에 해당하는 것이 무엇인지 궁금합니다. TIL sort -u도 있습니다.
  • sort -n | uniq

    . 예를 들어 후행 및 선행 공백은 sort -n -u에서는 중복으로 표시되지만 전자에서는 표시되지 않습니다! echo -e 'test \n test' | sort -n -utest를 반환하지만 echo -e 'test \n test' | sort -n | uniq는 두 줄을 모두 반환합니다.

답변

한 가지 차이점은 uniq에 다음과 같은 유용한 추가 옵션이 많다는 것입니다. 비교를 위해 필드를 건너 뛰고 값의 반복 횟수를 계산합니다. sort “의 -u 플래그는 장식되지 않은 uniq 명령의 기능 만 구현합니다.

p>

댓글

  • 유용한 답변을 위해 +0.49를 입력했지만 " sort -u는 후자의 일부를 사용하기 위해 ' uniq에 전달할 수 없습니다. '의 유용한 옵션입니다. "
  • +1하여 " ' 정렬에서 직접이 작업을 수행 할 수 없기 때문에 " 질문에 대답합니다

답변

POSIX 호환 sortuniq (GNU uniq는 현재 이와 관련하여 규정을 준수하지 않음), 차이가 있습니다. sort는 로케일의 조합 알고리즘을 사용하여 문자열을 비교합니다 (일반적으로 strcoll()를 사용하여 문자열 비교). div id = “7787430faf”>

는 바이트 값 ID를 확인합니다 (일반적으로 strcmp() 사용) ¹.

적어도 두 가지 이유로 중요합니다. .

  • 일부 로케일, 특히 GNU 시스템에는 동일한 정렬을하는 다른 문자가 있습니다. 예를 들어, GNU 시스템의 en_US.UTF-8 로켈에서 모든 ①②③④⑤⑥⑦⑧⑨⑩ … characters² 및 기타 많은 문자는 정렬 순서가 정의되지 않았기 때문에 동일하게 정렬됩니다. 0123456789 아라비아 숫자는 동부 아랍어 인도어 대응 숫자 (٠١٢٣٤٥٦٧٨٩)와 동일하게 정렬됩니다.

    sort -u, ①은 ②와 동일하게, 0123은 ٠١٢٣와 동일하게 정렬하므로 sort -uuniq의 경우 각각 하나만 유지합니다. (strcoll()를 사용하는 GNU uniq가 아닙니다 (-i 제외)), ①은 다릅니다 ②와 0123은 ٠١٢٣과 다르므로 uniq는 4 개를 모두 고유 한 것으로 간주합니다.

  • strcoll는 유효한 문자의 문자열 만 비교할 수 있지만 (입력에 유효한 문자를 형성하지 않는 바이트 시퀀스가있을 때 POSIX에 따라 동작이 정의되지 않음) strcmp()는 상관하지 않습니다. 바이트 간 비교 만 수행하므로 문자에 대해. 이것이 바로 sort -u 중 일부가 유효한 텍스트를 구성하지 않는 경우 고유 한 모든 줄을 제공하지 못하는 또 다른 이유입니다. sort|uniq 텍스트가 아닌 입력에 대해서는 아직 지정되지 않았지만 실제로는 이러한 이유로 고유 한 줄을 제공 할 가능성이 더 높습니다.

이러한 미묘함 외에도 uniq는 전체 줄을 어휘 적으로 비교하는 반면 sort “는 uniq입니다. div id = “520f34fd9e”>

는 명령 줄에 지정된 정렬 사양을 기준으로 비교합니다.

$ printf "%s\n" "a b" "a c" | sort -uk 1,1 a b $ printf "%s\n" "a b" "a c" | sort -k 1,1 | uniq a b a c $ printf "%s\n" 0 -0 +0 00 "" | sort -n | uniq 0 -0 +0 00 $ printf "%s\n" 0 -0 +0 00 "" | sort -nu 0 

¹ POSIX 사양의 이전 버전은 LC_COLLATE 변수를 uniq에 영향을 미치는 변수로 나열하여 혼란을 야기했습니다. 이는 2018 년 버전에서 제거되었으며 위에서 언급 한 논의에 따라 행동이 명확 해졌습니다. 해당하는 Austin 그룹 버그

² 2019를 참조하세요. 수정 . 그 이후로 수정되었지만 유니 코드 코드 포인트의 95 % 이상이 GNU libc 버전 2.30부터 정의되지 않은 순서를 가지고 있습니다 . 대신 🧙🧚🧛🧜🧝로 테스트 할 수 있습니다. 예를 들어 최신 버전

답변

사용하는 것을 선호합니다. sort | uniq 왜냐하면 -u (중복 제거) 옵션을 사용하여 대소 문자가 혼합 된 문자열을 포함하는 중복을 제거하려고 할 때 쉽지 않기 때문입니다. 결과를 이해하십시오.

참고 : 아래 예제를 실행하기 전에 다음을 수행하여 표준 C 데이터 정렬 시퀀스를 시뮬레이션해야합니다.

LC_ALL=C export LC_ALL 

예를 들어 파일을 정렬하고 중복 항목을 제거하는 동시에 서로 다른 문자열 대소 문자를 구분하려는 경우입니다.

$ cat short #file to sort Pear Pear apple pear Apple $ sort short #normal sort (in normal C collating sequence) Apple #the lower case words are at the end Pear Pear apple pear $ sort -f short #correctly sorts ignoring the C collating order Apple #but duplicates are still there apple Pear Pear pear $ sort -fu short #By adding the -u option to remove duplicates it is apple #difficult to ascertain the logic that sort uses to remove Pear #duplicates(i.e., why did it remove pear instead of Pear?) 

이 혼동은 -u 옵션을 사용하여 중복 항목을 제거하지 않으면 해결됩니다. uniq를 사용하는 것이 더 예측 가능합니다. 아래는 먼저 대소 문자를 분류하고 무시한 다음 uniq에 전달하여 중복을 제거합니다.

$ sort -f short | uniq Apple apple Pear pear 

댓글

  • -u sort 옵션은 첫 번째 동일한 실행 (맨 페이지 참조). 따라서 sort -fu는 대소 문자를 구분하지 않는 모든 고유 한 줄의 첫 번째 항목을 선택합니다. sort가 중복 항목을 제거하는 데 사용하는 논리는 예측 가능합니다.

답변

오늘 알아 낸 또 다른 차이점은 sort -u가 사용자가 정렬하는 열에 만 고유 플래그를 적용하는 구분 기호를 기준으로 정렬 할 때입니다.

$ cat input.csv 3,World,1 1,Hello,1 2,Hello,1 $ cat input.csv | sort -t"," -k2 -u 1,Hello,1 3,World,1 $ cat input.csv | sort -t"," -k2 | uniq 1,Hello,1 2,Hello,1 3,World,1 

댓글

  • 이것은 St é phane Chazelas의 답변에서 언급되었지만 귀하의 예가 마음에 듭니다. +1
  • @roaima를 지적 해 주셔서 감사합니다. ' 그 답변이 명확하지 않았습니다.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다