約 200 万のファイルを含むディレクトリ リストを取得する必要がありますが、ls
コマンドを実行しても何も返されません。3時間待ちました。試してみましls | tee directory.txt
たが、それは永遠にハングしているようです。
サーバーは多くの inode ソートを行っていると思います。ls
ファイル名のディレクトリ リストを取得するコマンドを高速化する方法はありますか? 現時点では、サイズ、日付、許可などは気にしません。
ls -U
ソートせずに ls を実行します。
速度低下のもう 1 つの原因は--color
. 一部の Linux マシンでは--color=auto'
、ls 呼び出しに追加される便利なエイリアスがあり、見つかった各ファイルのファイル属性を調べて (低速)、表示に色を付けます。ls -U --color=never
これはまたはで回避できます\ls -U
。
私は 400 万個のファイルを含むディレクトリを持っていますが、最初に大量のファイルをかき回すことなくすぐにファイルを吐き出すように ls を取得する唯一の方法は、
ls -1U
使用してみてください:
find . -type f -maxdepth 1
これは、ディレクトリ内のファイルのみを一覧表示します-type f
。ファイルとディレクトリを一覧表示する場合は、引数を省略します。
使用する
ls -1 -f
は約 10 倍速く、簡単に実行できます (100 万ファイルでテストしましたが、元の問題は 6 800 000 000 ファイルでした)。
しかし、私の場合、特定のディレクトリに10000を超えるファイルが含まれているかどうかを確認する必要がありました。10,000 個を超えるファイルがあった場合、ファイルがいくつあるかはもう気にしません。プログラムを終了して、実行を高速化し、残りを 1 つずつ読み取ろうとしないようにします。10,000 未満の場合は、正確な金額を印刷します。パラメータにファイルの量よりも大きな値を指定すると、私のプログラムの速度は ls -1 -f と非常に似ています。
次のように入力して、現在のディレクトリで私のプログラム find_if_more.pl を使用できます。
find_if_more.pl 999999999
n 個を超えるファイルがあるかどうかだけに関心がある場合、スクリプトは非常に大量のファイルで ls -1 -f よりも速く終了します。
#!/usr/bin/perl
use warnings;
my ($maxcount) = @ARGV;
my $dir = '.';
$filecount = 0;
if (not defined $maxcount) {
die "Need maxcount\n";
}
opendir(DIR, $dir) or die $!;
while (my $file = readdir(DIR)) {
$filecount = $filecount + 1;
last if $filecount> $maxcount
}
print $filecount;
closedir(DIR);
exit 0;
出力をリダイレクトし、バックグラウンドで ls プロセスを実行できます。
ls > myls.txt &
これにより、実行中のビジネスについて続けることができます。それはあなたのシェルをロックしません。
ls を実行して返されるデータを減らすためのオプションについてはわかりません。いつでも実行man ls
して確認できます。
これはおそらく役立つ答えではありませんが、持っていない場合は、これでfind
間に合うかもしれませんtar
$ tar cvf /dev/null .
私よりも年上の人々から、「昔は」、シングルユーザーおよびリカバリ環境は現在よりもはるかに制限されていたと言われました。それがこのトリックの由来です。
GNU ls を使用していると思いますか? 試す
\ls
通常の ls (ls --color=auto) のエイリアスを解除します。
プロセスが「戻ってこない」場合は、straceを使用して、プロセスがオペレーティング システムとどのようにやり取りしているかを分析することをお勧めします。
ls の場合:
$strace ls
実際に何かを出力する前に、すべてのディレクトリ エントリ ( getdents(2) ) を読み取ることがわかります。(並べ替え…ここですでに述べたように)
いくつかのフォローアップ:実行しているOSについては言及していません。これは、使用しているlsのバージョンを示すのに役立ちます。これはおそらく、lsの質問ほど「bash」の質問ではありません。私の推測では、あなたはGNU lsを使用していると思います。これは、いくつかのコンテキストで役立ついくつかの機能を備えていますが、大きなディレクトリではあなたを殺します。
GNUls列をよりきれいに配置しようとしています。GNU lsは、すべてのファイル名をスマートに配置しようとします。巨大なディレクトリでは、これにはある程度の時間とメモリが必要です。
これを「修正」するには、次のことを試してください。
ls -1
#列がまったくない
BSD lsをどこかhttp://www.freebsd.org/cgi/cvsweb.cgi/src/bin/ls/で見つけて、それを大きなディレクトリで使用してください。
検索などの他のツールを使用する
どのパーティションタイプを使用していますか?
1つのディレクトリに数百万の小さなファイルがある場合は、多くの小さなサイズのファイルでパフォーマンスが向上するJFSまたはReiserFSを使用することをお勧めします。
どうですかfind ./ -type f
(現在のディレクトリ内のすべてのファイルを検索します)?すべてを見つけるために離陸し-type f
ます。
試すこと:
ls がエイリアス化されていないことを確認しますか?
alias ls
おそらく、代わりに検索してみてください。
find . \( -type d -name . -prune \) -o \( -type f -print \)
お役に立てれば。
ここには他にも多くの優れたソリューションがありますが、完全を期すために:
echo *
xargsを利用することもできます。lsの出力をxargsにパイプするだけです。
ls | xargs
それが機能せず、上記の検索例が機能しない場合は、問題を引き起こしている可能性のあるメモリ使用量に役立つ可能性があるため、それらをxargsにパイプしてみてください。