sort 명령은 원하는 대로 데이터를 추가/제거합니다.

sort 명령은 원하는 대로 데이터를 추가/제거합니다.

sort여기에서 다운로드한 rockyou.txt 단어 목록을 정렬하는 명령을 사용하고 있습니다 .장소:

% sort rockyou.txt > rockyou_sorted.txt

그런데 두 파일의 파일 크기를 확인해 보니 서로 다른데요,이것 정렬된 파일이 더 작습니다.:

% du -shk rockyou_sorted.txt rockyou.txt 
147520  rockyou_sorted.txt
148304  rockyou.txt

흥미롭게도 다음에서 다운로드한 rockyou.txt 단어 목록의 클린 버전을 사용하여 동일한 단계를 반복했을 때여기, 나는 반대 결과를 얻습니다.정렬된 파일이 더 큽니다.:

% sort rockyou_cleaned.txt > rockyou_cleaned_sorted.txt
% du -shk rockyou_cleaned_sorted.txt rockyou_cleaned.txt 
114752  rockyou_cleaned_sorted.txt
102104  rockyou_cleaned.txt

이유를 알고 싶습니다. 누군가 나에게 이것을 설명해 줄 수 있습니까? 내가 뭐 잘못 했어요? 정렬된 파일과 원본 파일의 크기가 같아야 할 것 같은데요?

업데이트 1, 아래 Francesco Lucianò의 설명에 따라: sort-o 매개변수와 함께 명령을 사용하십시오.

% sort rockyou.txt -o rockyou_sorted_sO.txt
% du -shk rockyou_sorted_sO.txt rockyou.txt
147996 /Users/Martin/Downloads/rockyou_sorted_sO.txt
148304 /Users/Martin/Downloads/rockyou.txt

정렬된 파일은 여전히 ​​원본보다 작지만 sort위 명령 버전을 사용할 때만큼 작지는 않습니다.

줄 수는 모든 파일에서 동일합니다.

% wc -l rockyou_sorted_sO.txt rockyou_sorted.txt rockyou.txt
14344391 rockyou_sorted_sO.txt
14344391 rockyou_sorted.txt
14344391 rockyou.txt
43033173 total 

업데이트 2, 아래 bey0nd의 설명에 따라: set | grep LANG아무것도 출력하지 않습니다.

% set | grep LANG
%

% chardet rockyou* 
zsh: command not found: chardet
% uchardet rockyou*
rockyou.txt: UTF-8
rockyou_sorted.txt: UTF-8
rockyou_sorted_duplicut.txt: UTF-8
rockyou_sorted_sO.txt: UTF-8

업데이트 3, Steeldriver가 아래에 설명했듯이:

% system_profiler SPSoftwareDataType
Software:

    System Software Overview:

      System Version: macOS 10.15.4 (19E287)
      Kernel Version: Darwin 19.4.0
      Boot Volume: Macintosh HD
      Boot Mode: Normal
      Computer Name: *REDACTED* MacBook Pro
      User Name: *REDACTED*
      Secure Virtual Memory: Enabled
      System Integrity Protection: Enabled
      Time since boot: 6 days 4:57

파일 시스템은 APFS입니다.

업데이트 4, roaima의 의견에 따르면 다음과 같습니다.

% ls -l rockyou*
-rw-r--r--@ 1 **REDACTED**  staff  139921497 May 16 12:24 rockyou.txt
-rw-r--r--  1 **REDACTED**  staff  139921847 May 16 12:25 rockyou_sorted.txt
-rw-r--r--  1 **REDACTED**  staff  139919642 May 16 12:29 rockyou_sorted_duplicut.txt
-rw-r--r--  1 **REDACTED**  staff  139921847 May 16 13:19 rockyou_sorted_sO.txt

% stat -f .
.

업데이트 5, Isaac의 의견에 따르면 다음과 같습니다.

% head -n3 rockyou.txt | od -An -tcx1 
           1   2   3   4   5   6  \n   1   2   3   4   5  \n   1   2   3
           31  32  33  34  35  36  0a  31  32  33  34  35  0a  31  32  33
           4   5   6   7   8   9  \n                                    
           34  35  36  37  38  39  0a 

% LC_ALL=C sort rockyou.txt >rockyou_sorted_with_LC.txt
% du -shk rockyou_sorted_with_LC.txt rockyou.txt
147520  rockyou_sorted_with_LC.txt
140476  rockyou.txt
% wc -l rockyou_sorted_with_LC.txt rockyou.txt
 14344391 rockyou_sorted_with_LC.txt
 14344391 rockyou.txt
 28688782 total

업데이트 6, 아래 fra-san의 의견은 다음과 같습니다.

% sort --version
2.3-Apple (101.40.1)
% locale        
LANG=""
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL="en_US.UTF-8"

답변1

가지다여기서 무슨 일이 일어나고 있는지, 그들은 서로 반대되는 방식으로 작동합니다.

  1. 입력 파일의 인코딩이 일관되지 않아 sort유효한 UTF-8로 변환되었습니다. 이렇게 하면 파일이. 이는 ls -l보고서 크기에 영향을 미칩니다.
  2. 파일 시스템 저장소에 이상한 일이 발생합니다. 파일 생성 방법에 따라 동일한 크기의 파일이 사용하는 블록 수가 변경됩니다. 이는 du -shk보고서의 크기에 영향을 미치며 주로더 작은(그러나 어느 쪽이든 갈 수 있습니다).

두 번째 점보다 첫 번째 점에 대해 더 정확하게 설명할 수 있지만, 짧은 대답은 이것이 du특히 APFS에서 개별 파일의 크기를 측정하는 데 적합한 도구가 아니라는 것입니다.

다음 두 섹션에서는 이 두 가지 요소를 심층적으로 살펴보겠습니다.


요소 (1)의 경우 파일에는 macOS의 기본 로캘 인코딩인 UTF-8로 인코딩되지 않은 줄이 포함되어 있습니다.sort명령은 출력에서 ​​잘못 인코딩된 줄을 수정하여 파일을 더 크게 만듭니다.. 아래에서 더 자세히 조사하겠지만 이는 짧은 답변일 뿐이므로 충분하다면 다음 섹션으로 건너뛸 수 있습니다.

제공된 파일을 C 로케일로 정렬한 다음 다시 en_US.UTF-8 로케일로 정렬하면 두 파일의 실제 크기가 다릅니다.

139921497 rockyou.txt
139921497 rockyou_c.txt
139921847 rockyou_sorted.txt

C 정렬 파일과 UTF-8 정렬 파일의 첫 번째 차이점은 다음과 같습니다.

299c299
<  �R3CKL3$$�
---
>  R3CKL3$$

첫 번째 줄에는 비밀번호의 시작과 끝에 바이트 0x93 및 0x94가 포함되어 있습니다. 이는 UTF-8의 유효한 독립 바이트가 아닙니다(멀티바이트 문자의 연속 바이트로만 나타날 수 있음). 두 번째에는 각각 2바이트의 UTF-8 C2 93C2 94.

밝혀지다원래의 만자 라인은 12바이트 라인으로 작성되었습니다.. 전체 파일에서 이러한 변경 사항은 원본 파일과 비교하여 정렬된 파일에 350바이트를 추가합니다.

나는 여기서 무슨 일이 일어나고 있는지 믿습니다.

  1. 원래 줄은 “R3CKL3$$”(따옴표 포함) 다음과 같이 인코딩됩니다.Windows-1252 코드 페이지(cp1252). 이 인코딩의 따옴표 쌍은 0x93과 0x94입니다.
  2. 다른 많은 항목과 마찬가지로 인코딩을 고려하지 않고 원시 바이트로 이 세트에 추가됩니다.
  3. 실제 Latin-1 ISO 8859-1에서는 바이트 범위 0x80-0x9f가 비어 있지만 ISO-8859-1(추가 하이픈 참고)에서는 다음으로 채워집니다.C1 제어 문자.
  4. 모든 ISO-8859-1은 블록으로 인코딩됩니다."라틴어-1 보충"유니코드에서 코드 포인트는 원시 바이트 값에 해당하며 C2 80멀티 C2 BF바이트 인코딩 C3 80으로 표현됩니다.C3 BFUTF-8.
  5. macOS 정렬은 ISO-8859-1 시도에 따라 별도의 연속 바이트를 해석합니다.를 사용하고 다음과 같은 방식으로 정렬하기 위해 내부적으로 유니코드 문자열로 변환합니다. 정렬된 문자열에서 바이트 0x93은 U+0093이 됩니다.
  6. 이러한 번역된 문자열은 파일의 원래 줄 대신 UTF-8 형식으로 출력됩니다.

사이트의 다른 질문에서는 해결 방법에 대해 논의합니다.잘못 인코딩된 cp1252 파일나중에 그게 필요하다면.

POSIX 상태라인에 로케일에서 유효한 문자를 형성하지 않는 일련의 바이트가 포함되어 있으면 유틸리티의 동작이 정의되지 않습니다.이는 표준에 의해 엄격히 허용됩니다.일관성 오류가 아닙니다. 이것은 적어도 예상치 못한 일이며 아마도 동작 버그일 것입니다. 내가 시도한 다른 구현에서는 이런 식으로 동작하지 않습니다.

이 요인으로 인해 파일이 약간더 큰정렬하면 실제로 더 커집니다. 파일에서 읽으면 더 많은 바이트를 얻게 됩니다.


요인 (2)는 일반적으로 파일을 "더 작게" 만들지만 이는 약간의 착각입니다. 파일을 읽으면 du크기가 다르기 때문에 반드시 더 많거나 적은 바이트가 생성되는 것은 아닙니다 .

du -shk일반적으로 이는 파일 크기를 확인하는 데 적합한 방법이 아닙니다.

du 유틸리티는 각 파일 매개변수에 대한 파일 시스템 블록 사용량을 표시합니다.

즉, 논리적 크기보다는 파일이 차지하는 물리적 공간의 양에 대한 정보를 보고합니다. 파일 시스템 및 관련 파일의 특정 매개변수에 따라 블록 수가 예상한 것과 크게 다를 수 있습니다. 거기파일을 전체 장치에 압축하는 경우와 같이 블록 수가 유용한 상황이 있지만 일반적으로 그렇지 않습니다.

요즘 블록 수가 더 이상 유용하지 않은 이유 중 하나는최신 파일 시스템이 항상 주어진 대로 정확하게 데이터를 기록하는 것은 아닙니다.: 예를 들어 더 크거나 더 작은 범위에 저장하기 전에 자동으로 압축하여 더 적은 수의 블록이 필요하거나 나중에 더 많은 블록을 사용하기 쉽도록 블록 내에 빈 공간을 남겨 둘 수 있습니다. 스파스 파일은 제로 블록을 생략하지만 중복 제거는 그 이상을 수행합니다.

APFS는 압축, 일부 중복 제거 및 델타 인코딩, 암호화 및 고급 메타데이터를 위한 여러 알고리즘을 지원합니다. 이들 중 일부 또는 전부가 작용할 수 있습니다.투명 압축에 대한 가장 가능한 변경 사항파일이 작성되는 시기는 애플리케이션 구현 및 시스템 로드에 따라 다릅니다.

cat파일을 몇 번만 확인 하면 차이점을 알 수 있습니다. 이미 rockyou.txt다운로드 한 경우 curl -O:

  • cat rockyou.txt > rockyou2.txt동일한 바이트 수(139921497)이지만 블록 수가 다른 파일을 생성합니다( curl생성된 파일은 147504 이고 생성된 파일은 147460 cat).
  • 새 파일을 캡처하면 (150512)와 마찬가지로 또 다른 블록 수(147520)가 제공됩니다 cp.
  • 두 줄을 다시 실행하면 나에게다른 결과첫 번째 시도보다 낫습니다.

정확한 이유도 모르겠고, 설명할 합리적인 방법도 있는지 모르겠습니다. 나는 때때로 다른 때보다 데이터를 압축하기 위해 더 열심히 노력하고 있다고 생각합니다. 모든 경우에 파일 크기는 사실상 동일하며 모든 버전에서 읽으면 동일한 바이트가 반환됩니다. APFS나 기타 최신 고성능 파일 시스템에 보고된 블록 수에서는 유용한 정보를 많이 얻지 못합니다. 파일을 장치에 압축하는 경우 가장 작은 버전을 얻기 위해 몇 번 시도하는 것이 도움이 될 수 있지만 그렇지 않으면 고려할 가치가 없습니다.


전반적으로 우리는인코딩 문제로 인해 파일이 실제로 약간 더 커집니다., 오프셋보고된 파일 시스템 동작을 약간 수정합니다.블록 수파일이 클수록 테스트 시 크기가 작아집니다. 실제 크기 측정 결과는 정렬 후 350바이트의 일관된 증가를 보여줍니다. 어떻게 보느냐에 따라 이것은 일종의 버그일 수도 있고, 버그일 수도 있습니다.사용잘못된 파일을 제공하여 정렬했습니다.

관련 정보