2022/07/21

lsとfindについて

大量のファイルを扱う際に、lsでファイルを表示するのがいいのかfindでファイルを表示するのがいいのか
迷うことがあったのでその違いと特徴についてまとめておく。

そのままコマンドを使った場合の違い

$ seq 10|xargs -I@ touch @.txt
$ ls
1.txt   2.txt  4.txt  6.txt  8.txt
10.txt  3.txt  5.txt  7.txt  9.txt
$ find
.
./3.txt
./1.txt
./2.txt
./7.txt
./6.txt
./9.txt
./4.txt
./8.txt
./10.txt
./5.txt

lsはファイル名を横並び(スペース分割)且つソートされてファイル名のみの出力
findは改行でカレントディレクトリから表示

大量のファイル処理

大量のファイルを処理する場合どうなるか、時間を計測して検証してみる
ひとまず1000ファイル

$ seq 1000| xargs -I@ touch @.txt
$ time ls
...
...
...
277.txt   457.txt  637.txt  817.txt  998.txt
278.txt   458.txt  638.txt  818.txt  999.txt

real    0m0.019s
user    0m0.007s
sys     0m0.012s

$ time find
...
...
...
./756.txt
./619.txt
./571.txt
./516.txt

real    0m0.019s
user    0m0.003s
sys     0m0.016s

次は思い切って1000000ファイル

$ seq 1000000|xargs -I@ touch @.txt
$ tree ../tmp
...
...
├── 99997.txt
├── 99998.txt
└── 99999.txt

0 directories, 463356 files
$  rm -r *.txt
bash: /usr/bin/rm: 引数リストが長すぎます
ush: /usr/bin/rm: 引数リストが長すぎます

ファイル数が大きすぎるのか、自分の気が短いのかわからないが、ファイル作成処理がうまく行かない…。
treeで確認したら、463356fileしか作られてなかったので、次は500000ファイルで試してみよう。
しかも中途半端?とはいえ作成されたファイルの数が大きすぎてワイルドカードを使うと引数が大きすぎるので、こういうときは大元のディレクトリから削除するのがいい。

ファイル名出力にどれだけの時間がかかるか実行
.txtをつけると重たくなって正常にファイルが作成されないので数字だけのファイル名にした。

$ seq 500000|xargs touch
$ time find
...
...
./499990
./499996

real  0m1.403s
user  0m0.556s
sys   0m0.695s

$ time ls
...
...
137497  174998  212497  249999  287499  324999  362499  40      4375    4750    625
137498  174999  212498  25      2875    325     3625    400     43750   47500   6250

real  0m2.871s
user  0m1.731s
sys   0m0.747s

findは一行一行出力していくのに対して、lsはソートして一行でまとめて出力するからか、一旦動作が止まったように見える。
もっとファイル数を多くしたらメモリの数値なんかにも変化が出てくるんかな?
正直今回の実行ではメモリの数値に特に大きな差はなかった。

まとめ

上記の通り
次は各コマンドのオプションなんかも調べてソートなし且つ即時出力なんかを指定できればlsとfindはほぼ同じ速度で動くかどうかを見たい。