私はsort
コマンドを使用して、これからダウンロードしたrockyou.txtワードリストをソートします site :
% sort rockyou.txt > rockyou_sorted.txt
ただし、両方のファイルのファイルサイズを確認すると、サイズが異なりますtheソートされたファイルの方が小さい:
% 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
なんでそれ?誰かが説明してくれませんか?私は何か間違ったことをしていますか?ソートされたファイルと元のファイルの両方が同じサイズである必要があると思いますか?
UPDATE 1、以下のFrancescoLucianòのコメントに従って:-oパラメータを指定したこのsort
コマンドの使用
% 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
UPDATE 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です。
UPDATE 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、以下のアイザックのコメントに従って:
% 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
UPDATE 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"
ここでは2つのことが起こり、それらは互いに相反して機能します。
sort
によって有効なUTF-8に変換されます。これにより、ファイルがbiggerになります。これは、ls -l
- reportedサイズに影響します。du -shk
- reportedのサイズに影響し、ほとんどの場合smallerになります(ただし、どちらの方法でもかまいません)。最初のポイントについて2番目よりも正確に説明できますが、du
は、特にAPFSで個々のファイルサイズを測定するための適切なツールではないということです。
次の2つのセクションでは、両方の要素の雑草について詳しく説明します。
要因(1)の場合、ファイルにはUTF-8エンコードされていない行が含まれています。これはmacOSのデフォルトのロケールエンコードです。 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番目には、UnicodeコードポイントU + 0093およびU + 0094が含まれ、それぞれ2バイトのUTF-8、C2 93
およびC2 94
としてエンコードされます。
その結果、元の10バイトの行が12バイトの行として書き出されます。ファイル全体で、これらの変更により、元のファイルよりもソートされたファイルに最大350バイト追加されます。
ここで起こったと私が信じているのは:
“R3CKL3$$”
(引用符を含む)で、 Windows-1252コードページ (cp1252)でエンコードされていました。ペアの引用符は、そのエンコーディングでは0x93と0x94です。C2 80
〜C2 BF
およびC3 80
〜C3 BF
で表されます。 TF-8 で。サイトの他の質問では、必要に応じて、事実の後に misencoded cp1252 file を修正する方法について説明しています。
POSIXが注記 ロケールで有効な文字を形成しないバイトシーケンスが行に含まれている場合、ユーティリティの動作は定義されていないため、これは、 standardであり、適合バグではありません。それはまだ少なくとも予期せぬことであり、間違いなく行動上のバグです。私が試した他の種類の実装は、このように動作しません。
この要因により、ファイルをソートするとわずかに大きくなり、本当に大きくなる-ファイルから読み取ると、より多くのバイトが取得されます。
要因(2)は、全体としてファイルが「小さくなる」ことを要求しますが、それは幻想のようなものです。 du
がサイズが異なると言っているからといって、ファイルを読み取っても必ずしもバイト数が増減するわけではありません。
du -shk
は一般に、ファイルサイズをチェックする適切な方法ではありません。
Duユーティリティは、各ファイル引数のファイルシステムブロック使用状況を表示します
つまり、論理サイズではなく、ファイルが占める物理スペースの量に関する情報を報告します。ファイルシステムと問題のファイルの正確なパラメーターに応じて、ブロック数は予想とはかなり異なる場合があります。ファイルをデバイス全体に圧縮する場合など、通常はそうではない場合など、ブロック数が役立つケースがあります。
現代のファイルシステムは常に与えられたとおりにデータを正確に書き込むとは限らない:たとえば、ブロックカウントが今日あまり役に立たない理由の1つ:たとえば、前にサイレントで圧縮する可能性があるより多くまたはより少ない範囲でそれを格納し、必要なブロックを少なくするか、ブロック内に空のスペースを残して、より多くのブロックを使用して将来の挿入を容易にします。スパースファイルはゼロのブロックを省略しますが、重複排除はそれよりもさらに進む可能性があります。
APFSの場合、いくつかのアルゴリズム、一部の重複排除とデルタエンコーディング、暗号化、高度なメタデータを使用して圧縮をサポートします。これらの一部またはすべてが機能している可能性があります。アプリケーションの実装とシステムの負荷に応じて、ファイルが書き込まれるときの透過圧縮の変動の可能性が最も高いです。
数回ファイルをcat
するだけで、すでに違いがわかります。 rockyou.txt
でcurl -O
をダウンロードした場合:
cat rockyou.txt > rockyou2.txt
は、同じバイトカウント(139921497)でブロックカウントが異なるファイルを作成します(curl
- createdの147504とcat
'sの147460)cp
(150512)と同様に、もう一度別のブロック数(147520)が得られます。それがなぜなのか正確にはわかりませんし、それを伝えるための合理的な方法があるのかわかりません。他のデータよりもデータを圧縮するのに苦労したことがあります。すべての場合において、ファイルは実際には同じサイズであり、どのバージョンから読み取っても同じバイトが返されます。 APFSやその他の最新の高性能ファイルシステムで報告されたブロック数からは、あまり有用な情報が得られません。ファイルをデバイスに圧縮している場合は、最小バージョンを取得するために数回試行することが役立つ場合がありますが、それ以外の場合は検討する価値がありません。
全体的に、エンコード方式の問題があり、ファイルが本当にわずかに大きくなり、ファイルシステムの動作により、より大きなファイルのblock countが報告され、テストではファイルが小さくなります。真のサイズ測定は、ソート時に350バイトの一貫した増加を示しています。見方によっては、これはソートのバグかもしれませんし、useのソートにバグがあり、悪いファイルを与えているかもしれません。