web-dev-qa-db-ja.com

サイズではなくファイル/ディレクトリの数をカウントするdu

私は、何年にもわたって蓄積されたあらゆる種類のがらくたのあるハードドライブをクリーンアップしようとしています。 duはディスク使用量の削減に役立ちましたが、全体のサイズが原因ではなく、ファイルとディレクトリの総数が膨大であるため、全体としては依然として扱いにくくなっています。

duのようなものを実行できますが、ファイルサイズではなく、ファイルとディレクトリの数を数える方法はありますか?たとえば、ファイルは1、ディレクトリはその中のファイル/ディレクトリの再帰的な数+ 1です。

編集:もっと明確になっているはずです。 /内のファイル/ディレクトリの総数だけでなく、/home/usrなど、およびそれらのサブディレクトリ内のduはサイズを示します。

13
Jesse

次のPHPスクリプトがうまくいきます。

#!/usr/bin/php
<?php 

function do_scan($dir, $dev) {
  $total = 1;

  if (\filetype($dir) === 'dir' && \lstat($dir)['dev'] == $dev) {
    foreach (\scandir($dir) as $file) {
      if ($file !== '.' && $file !== '..') {
        $total += do_scan($dir . \DIRECTORY_SEPARATOR . $file, $dev);
      }
    }

    print "$total\t$dir\n";
  }

  return $total;
};

foreach (\array_slice($argv, 1) as $arg) {
  do_scan($arg, \lstat($arg)['dev']);
}

それをファイルに入れます(たとえば、「treesize」)、chmod +xそれを実行して./treesize . | sort -rn | less

4
Jesse

du --inodesは便利だと思いましたが、必要なduのバージョンがわかりません。 Ubuntu 17.10では、以下が機能します。

du --inodes      # all files and subdirectories
du --inodes -s   # summary
du --inodes -d 2 # depth 2 at most

| sort -nrと組み合わせると、含まれているiノードの数で降順​​でソートされます。

11
krlmlr

最も簡単な方法は_find /path/to/search -ls | wc -l_のようです

Findは、すべてのファイルとフォルダーをウォークスルーするために使用されます。
_-ls_すべての名前をリスト(印刷)します。これはデフォルトであり、省略してもほとんどすべてのシステムで同じように機能します。 (ほとんどの場合、デフォルトが異なる場合があるため)。これを明示的に使用するのは良い習慣です。

_find /path/to/search -ls_の部分だけを使用すると、すべてのファイルとディレクトリが画面に出力されます。


wcは単語数です。 _-l_オプションは、行数をカウントするように指示します。

いくつかの方法で使用できます。

  • トイレテストファイル
  • 猫テストファイル|トイレ

最初のオプションは、wcにファイルを開いて、そのファイルの行数、単語数、文字数をカウントさせます。 2番目のオプションは同じことを行いますが、ファイル名なしでstdinから読み取ります。


コマンドをパイプ_|_と組み合わせることができます。最初のコマンドからの出力は、2番目のコマンドの入力にパイプされます。したがって、_find /path/to/search -ls | wc -l_はfindを使用してすべてのファイルとディレクトリをリストし、出力をwcにフィードします。 Wc次に、行数をカウントします。

(他の代替手段は `ls | wc 'でしたが、findははるかに柔軟性があり、学ぶための優れたツールです。)


[コメント後に編集]

Findとexecを組み合わせると便利な場合があります。

例えば。 find / -type d ! \( -path proc -o -path dev -o -path .snap \) -maxdepth 1 -exec echo starting a find to count to files in in {} \;は/内のすべてのディレクトリを一覧表示し、検索したくないディレクトリを除外します。それぞれに対して前のコマンドをトリガーして、/内のフォルダーごとのファイルの合計を取得できます。

しかしながら:

  1. これはGNU特定の拡張-maxdepthを使用します。
    これはLinuxで機能しますが、UNIXでのみ機能するわけではありません。
  2. 私はあなたが実際にそれぞれのサブディレクトリごとにいくつかのfoファイルを必要としているのではないかと思います。
8
Hennes

ncd はこれに最適です!

Manページから、ディレクトリごとのカウントを表示し、カウント順に並べることもできます。

[...]
KEYS
       C   Order by number of items (press again for descending order)
[...]
       c   Toggle display of child item counts.

例えば:

ncdu output

2
jobevers

nix&Linuxからの投稿 に触発されたbashを使用するソリューションを次に示します。

find . -type d | while read -r dir; do \
    printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

.gitなど、詳細を表示したくないフォルダがある場合は、grepを使用してリストから除外できます。

find . -type d |grep -v "./.git/.*" | while read -r dir; do \
    printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
1
Don Kirkby

ディレクトリとファイルが/で区切られているという事実を利用します。このスクリプトはあなたの基準を満たしていますが、完全なソリューションを刺激するのに役立ちます。また、locateを使用してファイルのインデックスを作成することも検討してください。

geee: /R/tb/tmp
$ find  2>/dev/null | awk -F/ -f filez  | sort -n
files:  57
3       imagemagick
7       portage
10      colemak-1.0
25      minpro.com
42      monolith
80      QuadTree
117     themh
139     skyrim.stings
185     security-howto
292     ~t
329     skyrim
545     HISTORY
705     minpro.com-original
1499    transmission-2.77
23539   ugent-settings

>

$ cat filez
{
a[$2]++;     # $1= folder,  $2 = everything inside folder.
}

END {
        for (i in a) {
                if (a[i]==1) {files++;}
                else { printf "%d\t%s\n", a[i], i; }
        }
        print "files:\t" files
}

>

 $ time locate /  | awk -F/ -f /R/tb/tmp/filez  | sort -n
 files:  13
 2
 2       .fluxbox
 10      M
 11      BIN
 120     bin
 216     sbin
 234     boot
 374     R
 854     dev
 1351    lib
 2018    etc
 9274    media
 30321   opt
 56516   home
 93625   var
 222821  usr
 351367  mnt
 time: Real 0m17.4s  User 0m4.1s  System 0m3.1s