再帰的なファイル数の取得(例:「du」、サイズではなくファイル数)

再帰的なファイル数の取得(例:「du」、サイズではなくファイル数)

rsnapshotのパフォーマンスの問題のために、多数のファイルを含むディレクトリを繰り返し識別したいと思います。問題は、ファイルサイズではなく、特定のサブディレクトリにあるファイル数のようです。世代数(daily.0、daily.1、…)が揮発性ではなく、全体に比べてほとんど変わらないからです。ファイル数。

Unixコマンドがファイルサイズの合計ではなくファイル数だけを返す場合は、duこれが私が望むものです。

私はすでに1つ持っていますファイル数を出力するbashスクリプトみんな直接(サブディレクトリに再帰)しかし、常に待機しながら、ますます深く掘り下げなければならないので使いにくいです。

また、一つを見つけました。スクリプトをより深く掘り下げるただし、サブディレクトリのファイル数は要約しません。サブディレクトリではなく、このディレクトリのファイル数のみが表示されます。

必ずしもシェルスクリプトである必要はありません。私はRuby、Python、Perl、JavaScriptなどの他のスクリプト言語にオープンです。

例:

dir1/
   file1
   subdir1/
       file2, file3, file4, file5
   subdir2/
       file6, file7, file8
       subdir3/
           file9
dir2/
    fileA, fileB

希望の出力(サブディレクトリを一覧表示してトップにまとめます):

4   dir1/subdir1
1   dir1/subdir2/subdir3
4   dir1/subdir2
9   dir1/
2   dir2/

私は何ですか?いいえ必要なもの(合計のみ一覧表示):

9   dir1/
2   dir2/

そしていいえ.(ディレクトリ内のファイル数のみを一覧表示):

4   dir1/subdir1
1   dir1/subdir2/subdir3
3   dir1/subdir2
1   dir1/
2   dir2/

答え1

次のようにしてみてください。

find . -type f | perl -aF/ -lne 'for (my $i=0; $i < @F-1; ++$i) { print join("/",@F[0...$i]); }' | sort | uniq -c

find . -type f文書印刷:

./dir1/subdir2/file8
./dir1/subdir2/file7
./dir1/subdir2/subdir3/file9
./dir1/subdir2/file6
./dir1/file1
...

perl -aF/ -lne 'for (my $i=0; $i < @F-1; ++$i) { print join("/",@F[0...$i]); }'各ファイル名を./a/b/c一連のディレクトリに変換します../a./a/b

メモ:

ファイル名に改行文字が含まれていると機能しません。各ディレクトリにin hash -print0findin、-0およびputカウンタを使用できます。perl

編集する:

@Gillesの投稿に触発されました回答:

find . -depth -print0 |
perl -0 -ne '
my $depth = tr!/!/!;
for (my $i = $prev_depth; $i <= $depth; ++$i) { $totals[$i] = 0; }
if ( -f $_ ) {
  for (my $i = 0; $i <= $depth; ++$i) { ++$totals[$i]; }
} else {
  print "$totals[$depth]\t$_\n";
}
$prev_depth = $depth;
'

ファイル名の改行に適用されます。空のディレクトリで動作します。追加機能は必要ありませんsort | uniq -c

答え2

find(ディレクトリのサブディレクトリ内のすべてのファイルを含むディレクトリ内のすべてのファイルを繰り返すために使用できます)とwc(ファイルの行数を計算する)単一行はどうですか?

find <directory> | wc

<directory>すべてのファイルの数を計算したいディレクトリはどこにありますか?これにより、3つの数字が印刷されます。最初の数字はfindから返された行数です。デフォルトでは、ファイルとディレクトリを見つけると思うので、ファイルとディレクトリの総数(それ自体を含む)が提供されますfind<directory><directory>

findこれは非常に柔軟なコマンドです。実際にファイルだけに興味があり、ディレクトリ数を計算したくない場合

find <directory> -type f | wc

動作します。たとえば、深さに関係なく、現在のディレクトリに含まれているすべてのファイルの数を計算するには、次のようにします。

find . -type f | wc

注意:find基本的にシンボリックリンクなどは従いません。ファイルがさまざまなファイルシステムにある場合、または自分が所有するファイルシステムにある場合は、ほぼfindすべてを処理するように設定できるため、マニュアルページを確認する必要があります。また、これはwc行数なので、名前に改行を含むファイルがある場合(技術的には可能ですが、一般的に私が知る限り良い考えではない)、これに似た内容があれば興味深い答えを得ることができます。

答え3

私の意見によると、次のバリエーションがあなたのニーズに適している可能性があります。

find . -depth -type d -exec /bin/sh -c 'printf "%5d %s\n" "$(find {} -type f -printf . | wc -c)" "{}"' \;

(私はより深いサブディレクトリの結果を数回計算し、ファイルシステムキャッシュがある時点でツリーの完全なメタデータを持ち、毎回新しいシェルを作成すると予想しているので、正しく実行された旅団は間違いなく私を正しく撃つでしょう。これは始まりです。)

あなたのサンプル構造に基づいて、次のようになります。

    4 ./dir1/subdir1
    1 ./dir1/subdir2/subdir3
    4 ./dir1/subdir2
    9 ./dir1
    2 ./dir2
   11 .

(現在の作業ディレクトリを除外するには、externalfind .に変更するfind *か、find . -mindepth 1

関連情報