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
持つ二つここで何が起こっているのか、彼らは互いに反対の方法で動作します。
- 入力ファイルのエンコーディングが一貫していないため、
sort
有効なUTF-8に変換されました。これにより、ファイルが大きい。これはls -l
レポートサイズに影響します。 - ファイルシステムリポジトリに奇妙なことが起こります。ファイルの生成方法によって、同じサイズのファイルが使用するブロック数が変わります。これは
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 93
とC2 94
。
明らかにする元の万字線は12バイトの線で書かれていました。。フルファイルでは、これらの変更は元のファイルと比較してソートされたファイルに350バイトを追加します。
私はここで何が起こっているのか信じています。
- 元の行は
“R3CKL3$$”
(引用符を含む)次のようにエンコードされます。Windows-1252コードページ(cp1252)。このエンコーディングの引用符のペアは0x93と0x94です。 - 他の多くの項目と同様に、エンコードを考慮せずに生のバイトとしてこのセットに追加されます。
- 実際のLatin-1 ISO 8859-1ではバイト範囲0x80-0x9fが空ですが、ISO-8859-1(追加のハイフンを参照)では次のように入力されます。C1制御文字。
- すべてのISO-8859-1はブロックでエンコードされています。」ラテン語-1サプリメント「Unicodeでは、コードポイントは生のバイト値に対応し、
C2 80
マルチC2 BF
バイトエンコーディングC3 80
で表されます。C3 BF
UTF-8。 - macOSアライメントは、ISO-8859-1の試みに従って別々の連続バイトを解釈します。を使用し、次のようにソートするために、内部的にUnicode文字列に変換します。ソートされた文字列では、バイト0x93はU + 0093になります。
- これらの翻訳された文字列は、ファイルの元の行ではなくUTF-8形式で出力されます。
サイトの他の質問では、回避策について説明します。誤ってエンコードされたcp1252ファイル後でそれが必要な場合。
POSIXステータス行にロケールで有効な文字を形成しない一連のバイトが含まれている場合、ユーティリティの動作は定義されません。これは標準によって厳密に認められています。一貫性エラーではありません。これは少なくとも予期しないことであり、おそらく動作のバグです。私が試した他の実装では、このように動作しません。
この要因により、ファイルが少し大きいソートすると実際には大きくなります。ファイルから読み込むと、より多くのバイトが得られます。
要因(2)は通常ファイルを「小さく」しますが、これは少し錯覚です。ファイルを読み取るとdu
サイズが異なるため、必ずしも多くまたは少ないバイトが生成されるわけではありません。
du -shk
通常、これはファイルサイズを確認するのに適した方法ではありません。
duユーティリティは、各ファイルパラメータのファイルシステムブロック使用量を表示します。
つまり、論理サイズではなく、ファイルが占める物理スペースの量に関する情報を報告します。ファイルシステムと関連ファイルの特定のパラメータによって、ブロック数が予想したものと大きく異なる場合があります。そこはいファイルをデバイス全体に圧縮する場合など、ブロック数が便利な状況がありますが、通常はそうではありません。
最近のブロック数がもはや役に立たない理由の1つ最新のファイルシステムが常に指定されたとおりに正確にデータを記録するわけではありません。: たとえば、より大きいまたはより小さい範囲に保存する前に、自動的に圧縮して、より少ない数のブロックを必要とするか、または後でより多くのブロックを使いやすくするために、ブロック内に空きスペースを残すことができます.スパースファイルはゼロブロックを省略しますが、重複排除はそれ以上を行います。
APFSは、圧縮、いくつかの重複排除、デルタエンコーディング、暗号化、高度なメタデータのためのいくつかのアルゴリズムをサポートしています。これらの一部または全部が機能し得る。透明圧縮に対する最も可能な変更ファイルの作成時期は、アプリケーションの実装とシステムのロードによって異なります。
cat
ファイルを数回だけ確認すると、違いがわかります。すでにrockyou.txt
ダウンロードしている場合curl -O
:
cat rockyou.txt > rockyou2.txt
同じバイト数(139921497)でブロック数が異なるファイルを生成します(curl
生成されたファイルは147504、生成されたファイルは147460cat
)。- 新しいファイルをキャプチャすると(150512)、同様に別のブロック数(147520)が表示されます
cp
。 - 2行を再実行すると、私にその他の結果最初の試みよりも優れています。
正確な理由もわからないし、説明する合理的な方法もあるのか分からない。私は時々他の時よりもデータを圧縮するために一生懸命働いていると思います。いずれの場合も、ファイルサイズは事実上同じであり、すべてのバージョンで読み取ると同じバイトが返されます。 APFSやその他の最新の高性能ファイルシステムに報告されているブロック数では、有用な情報はあまり得られません。ファイルをデバイスに圧縮する場合は、最小バージョンを取得するために数回試すことが役に立ちますが、そうでない場合は考慮する価値はありません。
全体的に私たちはエンコーディングの問題により、ファイルは実際に少し大きくなります。、オフセット報告されたファイルシステムの動作を少し変更します。ブロック数ファイルが大きいほど、テスト時にサイズが小さくなります。実際のサイズ測定結果は、ソート後の350バイトの一貫した増加を示しています。どのように見ているかに応じて、これは何らかのバグかもしれませんし、バグかもしれません。使用間違ったファイルを提供してソートしました。