私はLinuxが初めてです。 Linuxに約250,000個のファイルがあるディレクトリがあり、パターンに一致するファイルの数を見つける必要があります。
私は次のコマンドを使用してみました:
ls -1 20061101-20131101_kh5x7tte9n_2010_* | wc -l
次のエラーメッセージが表示されました。
-bash: /bin/ls: Argument list too long
0
助けてください。前もって感謝します
これにはfind
を使用した方がよい場合があります。
find . -name "pattern_*" -printf '.' | wc -l
特定の場合:
find . -maxdepth 1 -name "20061101-20131101_kh5x7tte9n_2010_*" -printf '.' | wc -m
find
は、条件に一致するファイルのリストを返します。 -maxdepth 1
は、サブディレクトリなしでパスのみで検索を行います( thanks Petesh! )。 -printf '.'
は、一致するたびにドットを出力します。そのため、新しい行を持つ名前がwc -m
を壊すことはありません。
wc -m
は、ファイルの数と一致する文字数を示します。
2つの可能なオプションのパフォーマンス比較:
このパターンで10000個のファイルを作成しましょう。
$ for i in {1..10000}; do touch 20061101-20131101_kh5x7tte9n_201_$i; done
そして、ls -1 ...
またはfind ...
と結果を取得するのにかかる時間を比較します。
$ time find . -maxdepth 1 -name "20061101-20131101_kh5x7tte9n_201_*" | wc -l
10000
real 0m0.034s
user 0m0.017s
sys 0m0.021s
$ time ls -1 | grep 20061101-20131101_kh5x7tte9n_201 | wc -l
10000
real 0m0.254s
user 0m0.245s
sys 0m0.020s
find
はx5倍高速です!ただし、ls -1f
( Peteshに感謝! )を使用すると、ls
はfind
よりも高速です。
$ time ls -1f | grep 20061101-20131101_kh5x7tte9n_201 | wc -l
10000
real 0m0.023s
user 0m0.020s
sys 0m0.012s
これを試して:
ls -1 | grep 20061101-20131101_kh5x7tte9n_2010_ | wc -l
シェルがパターンをファイルのリストに展開するため、「引数が長すぎます」ということになります。試してください:
find -maxdepth 1 -name '20061101-20131101_kh5x7tte9n_2010_*' |wc -l
注意してください-シェルの拡張を防ぐために、パターンは引用符で囲まれています
通常、 スクリプト内でls
を避ける にする必要があります。実際、Shell関数で計算を実行すると、exec
がないため「引数リストが長すぎます」エラーを回避できます。境界などARGV_MAX
制限は関係ありません。
number_of_files () {
if [ -e "$1" ]; then
echo "$#"
else
echo 0
fi
}
グロブがまったく展開されないことを条件付きで保護します(これはデフォルトではデフォルトです。Bashでは、shopt -s nullglob
は、どのファイルにも一致しないワイルドカードを作成して、空の文字列に展開します)。
それを試してみてください:
number_of_files 20061101-20131101_kh5x7tte9n_2010_*