233

パターンに一致するファイルの数をカウントする bash コマンドはありますか?

たとえば、次のパターンに一致するディレクトリ内のすべてのファイルの数を取得したいとします。log*

4

16 に答える 16

318

この単純なワンライナーは、bash だけでなく、どのシェルでも機能するはずです。

ls -1q log* | wc -l

ls -1q は、空白や改行などの特殊文字が含まれている場合でも、ファイルごとに 1 行を提供します。

出力は、行数をカウントする wc -l にパイプされます。

于 2012-07-03T08:41:54.593 に答える
69

ここにはたくさんの答えがありますが、考慮されていないものもあります

  • スペース、改行、または制御文字を含むファイル名
  • ハイフンで始まるファイル名 ( というファイルを想像してください-l)
  • ドットで始まる隠しファイル (グロブ*.loglog*
  • グロブに一致するディレクトリ (たとえば、logs一致するという名前のディレクトリlog*)
  • 空のディレクトリ (つまり、結果は 0)
  • 非常に大きなディレクトリ (すべてを一覧表示すると、メモリが使い果たされる可能性があります)

それらすべてを処理するソリューションは次のとおりです。

ls 2>/dev/null -Ubad1 -- log* | wc -l

説明:

  • -Ulsエントリをソートしません。つまり、ディレクトリ リスト全体をメモリにロードする必要はありません。
  • -b非グラフィック文字の C スタイルのエスケープを出力し、決定的に改行が として出力され\nます。
  • -alog*隠しファイルを含むすべてのファイルを出力します (グロブが隠しファイルを意味しない場合は厳密には必要ありません)
  • -dディレクトリの内容を一覧表示しようとせずにディレクトリを出力します。これはls通常行うことです。
  • -1それが1つの列にあることを確認します(lsはパイプへの書き込み時にこれを自動的に行うため、厳密には必要ありません)
  • 2>/dev/nullログ ファイルが 0 の場合にエラー メッセージを無視するように stderr をリダイレクトします。(代わりに作業ディレクトリ全体をリストshopt -s nullglobする原因になることに注意してください。)ls
  • wc -lはディレクトリ リストを生成時に消費するため、 の出力はlsどの時点でもメモリ内にはありません。
  • ----ファイル名は、引数として理解されないように使用するコマンドから分離されますls(削除された場合log*)

シェルファイルの完全なリストに展開log*しますが、ファイルが多い場合はメモリを使い果たす可能性があるため、grep を使用して実行することをお勧めします。

ls -Uba1 | grep ^log | wc -l

この最後のものは、大量のメモリを使用せずにファイルの非常に大きなディレクトリを処理します (ただし、サブシェルを使用します)。現在のディレクトリの内容をリストするだけなので、これ-dは不要になりました。

于 2015-11-24T11:01:33.753 に答える
66

\nこれは、bash を使用して安全に行うことができます (つまり、スペースを含むファイルや名前にバグが発生することはありません)。

$ shopt -s nullglob
$ logfiles=(*.log)
$ echo ${#logfiles[@]}

ファイルが一致しない場合に配列nullglobにリテラルを取得しないように有効にする必要があります。(安全にリセットする方法の例については、「set -x」を「元に戻す」方法を参照してください。)*.log$logfiles

于 2012-07-03T08:43:34.363 に答える
59

再帰検索の場合:

find . -type f -name '*.log' -printf x | wc -c

wc -cの出力の文字数をカウントし、find結果ごとに 1 つの文字を出力する-printf xよう指示します。findx

非再帰検索の場合は、次のようにします。

find . -maxdepth 1 -type f -name '*.log' -printf x | wc -c
于 2012-07-03T08:41:00.897 に答える
11

この質問に対する受け入れられた回答は間違っていますが、担当者が少ないため、コメントを追加できません。

この質問に対する正しい答えは、Mat によって与えられます。

shopt -s nullglob
logfiles=(*.log)
echo ${#logfiles[@]}

受け入れられた回答の問題は、 wc -l が改行文字の数をカウントし、端末に「?」として出力されてもカウントすることです。「ls -l」の出力で。これは、ファイル名に改行文字が含まれている場合、受け入れられた回答が失敗することを意味します。提案されたコマンドをテストしました:

ls -l log* | wc -l

また、名前に改行文字が含まれているパターンに一致するファイルが 1 つしかない場合でも、誤って値 2 を報告します。例えば:

touch log$'\n'def
ls log* -l | wc -l
于 2015-10-30T06:11:52.067 に答える
0
ls -1 log* | wc -l

つまり、1行に1つのファイルをリストし、それを単語数コマンドにパイプして、パラメーターを数行に切り替えます。

于 2012-07-03T20:17:16.190 に答える
-1

すべてをカウントするには、ls を単語カウント行にパイプするだけです。

ls | wc -l

パターンでカウントするには、最初に grep にパイプします。

ls | grep log | wc -l
于 2020-02-06T16:05:24.867 に答える