sortコマンドは、必要に応じてデータを追加/削除します。

sortコマンドは、必要に応じてデータを追加/削除します。

sortここでダウンロードしたrockyou.txtの単語リストを並べ替えるコマンドを使用しています。場所:

% sort rockyou.txt > rockyou_sorted.txt

ところで、2つのファイルのファイルサイズを確認してみると、違いますが、これ ソートされたファイルが小さいです。:

% 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レポートのサイズに影響し、主に小さい(しかしどちらにでも行けます)。

2番目の点よりも最初の点についてより正確に説明できますが、短い答えは、これがdu特にAPFSで個々のファイルのサイズを測定するのに適したツールではないということです。

次の2つのセクションでは、これら2つの要素について詳しく説明します。


要素(1)の場合、ファイルにはmacOSのデフォルトのロケールエンコーディングであるUTF-8でエンコードされていない行が含まれています。このsortコマンドは、出力で誤ってエンコードされた行を修正してファイルを大きくします。。以下で詳しく調べますが、これは短い答えにすぎないので、十分であれば次のセクションに進むことができます。

指定されたファイルをCロケールで並べ替え、再びen_US.UTF-8ロケールで並べ替えると、2つのファイルの実際のサイズが異なります。

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

C ソートファイルと UTF-8 ソートファイルの最初の違いは次のとおりです。

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

最初の行には、パスワードの先頭と末尾にバイト0x93と0x94が含まれています。これはUTF-8の有効な独立バイトではありません(マルチバイト文字の連続バイトとしてのみ表示できます)。 2番目は、それぞれ2バイトのUTF-8C2 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サプリメント「Unicodeでは、コードポイントは生のバイト値に対応し、C2 80マルチC2 BFバイトエンコーディングC3 80で表されます。C3 BFUTF-8
  5. macOSアライメントは、ISO-8859-1の試みに従って別々の連続バイトを解釈します。を使用し、次のようにソートするために、内部的にUnicode文字列に変換します。ソートされた文字列では、バイト0x93はU + 0093になります。
  6. これらの翻訳された文字列は、ファイルの元の行ではなくUTF-8形式で出力されます。

サイトの他の質問では、回避策について説明します。誤ってエンコードされたcp1252ファイル後でそれが必要な場合。

POSIXステータス行にロケールで有効な文字を形成しない一連のバイトが含まれている場合、ユーティリティの動作は定義されません。これは標準によって厳密に認められています。一貫性エラーではありません。これは少なくとも予期しないことであり、おそらく動作のバグです。私が試した他の実装では、このように動作しません。

この要因により、ファイルが少し大きいソートすると実際には大きくなります。ファイルから読み込むと、より多くのバイトが得られます。


要因(2)は通常ファイルを「小さく」しますが、これは少し錯覚です。ファイルを読み取るとduサイズが異なるため、必ずしも多くまたは少ないバイトが生成されるわけではありません。

du -shk通常、これはファイルサイズを確認するのに適した方法ではありません。

duユーティリティは、各ファイルパラメータのファイルシステムブロック使用量を表示します。

つまり、論理サイズではなく、ファイルが占める物理スペースの量に関する情報を報告します。ファイルシステムと関連ファイルの特定のパラメータによって、ブロック数が予想したものと大きく異なる場合があります。そこはいファイルをデバイス全体に圧縮する場合など、ブロック数が便利な状況がありますが、通常はそうではありません。

最近のブロック数がもはや役に立たない理由の1つ最新のファイルシステムが常に指定されたとおりに正確にデータを記録するわけではありません。: たとえば、より大きいまたはより小さい範囲に保存する前に、自動的に圧縮して、より少ない数のブロックを必要とするか、または後でより多くのブロックを使いやすくするために、ブロック内に空きスペースを残すことができます.スパースファイルはゼロブロックを省略しますが、重複排除はそれ以上を行います。

APFSは、圧縮、いくつかの重複排除、デルタエンコーディング、暗号化、高度なメタデータのためのいくつかのアルゴリズムをサポートしています。これらの一部または全部が機能し得る。透明圧縮に対する最も可能な変更ファイルの作成時期は、アプリケーションの実装とシステムのロードによって異なります。

catファイルを数回だけ確認すると、違いがわかります。すでにrockyou.txtダウンロードしている場合curl -O:

  • cat rockyou.txt > rockyou2.txt同じバイト数(139921497)でブロック数が異なるファイルを生成します(curl生成されたファイルは147504、生成されたファイルは147460 cat)。
  • 新しいファイルをキャプチャすると(150512)、同様に別のブロック数(147520)が表示されますcp
  • 2行を再実行すると、私にその他の結果最初の試みよりも優れています。

正確な理由もわからないし、説明する合理的な方法もあるのか分からない。私は時々他の時よりもデータを圧縮するために一生懸命働いていると思います。いずれの場合も、ファイルサイズは事実上同じであり、すべてのバージョンで読み取ると同じバイトが返されます。 APFSやその他の最新の高性能ファイルシステムに報告されているブロック数では、有用な情報はあまり得られません。ファイルをデバイスに圧縮する場合は、最小バージョンを取得するために数回試すことが役に立ちますが、そうでない場合は考慮する価値はありません。


全体的に私たちはエンコーディングの問題により、ファイルは実際に少し大きくなります。、オフセット報告されたファイルシステムの動作を少し変更します。ブロック数ファイルが大きいほど、テスト時にサイズが小さくなります。実際のサイズ測定結果は、ソート後の350バイトの一貫した増加を示しています。どのように見ているかに応じて、これは何らかのバグかもしれませんし、バグかもしれません。使用間違ったファイルを提供してソートしました。

おすすめ記事