web-dev-qa-db-ja.com

ディレクトリブランチ内の特定のファイルの合計サイズを見つける

たとえば./photos/john_doeなどのイメージストレージディレクトリがあり、その中に複数のサブディレクトリがあり、そこに特定のファイルが多数あるとします(*.jpgなど)。 john_doeブランチの下のこれらのファイルの概要サイズを計算するにはどうすればよいですか?

du -hs ./photos/john_doe/*/*.jpgを試しましたが、これは個々のファイルのみを示しています。また、これはjohn_doeのようにjohn_doe/june/ディレクトリの最初のネストレベルのみを追跡しますが、john_doe/june/outrageous/はスキップします。

それで、特定のファイルのサイズを合計して、ブランチ全体をトラバースするにはどうすればよいですか?

162
mbaitoff
find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$

ファイルリストが非常に長いためにduの複数の呼び出しが必要な場合、複数の合計が報告され、合計する必要があります。

210
SHW
du -ch public_html/images/*.jpg | grep total
20M total

.jpgこのディレクトリのファイル。

複数のディレクトリを処理するには、おそらくこれをfindと組み合わせる必要があります。

duコマンドの例 が役立つかもしれません(findも含まれます)

55
Levon

主に、次の2つが必要です。

  • -cduのオプション。総計を生成するように指示します。
  • どちらか**アクティベーション手順 )またはfind )またはサブディレクトリをトラバースします。
du -ch -- **/*.jpg | tail -n 1

最終的な答えは:

{ find <DIR> -type f -name "*.<EXT>" -printf "%s+"; echo 0; } | bc

さらに高速なバージョンで、RAMによる制限はありませんが、GNU AWKとbignumのサポートが必要です。

find <DIR> -type f -name "*.<EXT>" -printf "%s\n" | gawk -M '{t+=$1}END{print t}'

このバージョンには次の機能があります。

  • 探しているファイルを指定するfindのすべての機能
  • 数百万のファイルをサポートします
    • ここでの他の回答は、引数リストの最大長によって制限されます
  • 最小限のパイプスループットで3つの単純なプロセスのみを生成します
    • ここでの多くの回答はC + Nプロセスを生成します。Cは定数で、Nはファイル数です。
  • 文字列操作を気にしません
    • このバージョンはgreppingや正規表現を行いません
    • まあ、findはファイル名の単純なワイルドカード照合を行います
  • オプションで合計を人間が読める形式にフォーマットします(例:5.5K176.7M、...)
    • それを行うには| numfmt --to=si
19
rindeal

これまでの回答では、findからduに渡されたファイルリストが長すぎて、リストが自動的にチャンクに分割され、totalが複数回発生する場合があることを考慮していません。

grep total(ロケール!)を手動で合計するか、別のコマンドを使用します。私の知る限り、findで見つかったすべてのファイルの総計(キロバイト単位)を取得する方法は2つしかありません。
find . -type f -iname '*.jpg' -print0 | xargs -r0 du -a| awk '{sum+=$1} END {print sum}'

説明
find . -type f -iname '*.jpg' -print0:大文字と小文字に関係なく、拡張子がjpgのすべてのファイルを検索し(* .jpg、*。JPG、*。Jpg ...)、それらを出力します(ヌル終了)。
xargs -r0 du -a:-r:引数が渡されていなくても、Xargsはコマンドを呼び出すため、-rはこれを防止します。 -0はnullで終了する文字列を意味します(改行で終了しない)。
awk '{sum+=$1} END {print sum}':前のコマンドによって出力されたファイルサイズを合計します

参考までに、他の方法は
find . -type f -iname '*.jpg' -print0 | du -c --files0-from=-

10
Jan

GNUシステムで、ファイルのリストが大きすぎてdu -cの1回の呼び出しに渡せない場合は、次のようにできます。

find . -iname '*.jpg' -type f -printf '%b\t%D:%i\n' |
  sort -u | cut -f1 | paste -sd+ - | bc

(512バイトブロックの数で表されるサイズ)。 duと同様に、ハードリンクを1回だけカウントしようとします。ハードリンクを気にしない場合は、次のように簡略化できます。

(printf 0; find . -iname '*.jpg' -type f -printf +%b) | bc

ディスクの使用量ではなくサイズが必要な場合は、%b%sに置き換えます。サイズはバイト単位で表されます。

4

これまでに説明したソリューションは非効率的で(execは高価です)、ファイルリストが長い場合や、Mac OS Xで機能しない場合は、合計するために追加の手動作業が必要です。次のソリューションは非常に高速で、どのシステムでも機能するはずです。合計の答えをGBで表示します(合計をMBで表示したい場合は、/ 1024を削除してください):find . -iname "*.jpg" -ls |Perl -lane '$t += $F[6]; print $t/1024/1024/1024 . " GB"'

2
hobbydad

duは自然にディレクトリ階層をトラバースし、awkはフィルタリングを実行できるため、次のようなもので十分です。

du -ak | awk 'BEGIN {sum=0} /\.jpg$/ {sum+=$1} END {print sum}'

これはGNUなしで動作します。

2
GeoffP

Zbyszekがコメントですでに指摘したように、SHWの優れた答えを改善して、どのロケールでも機能するようにします。

LC_ALL=C find ./photos/john_doe -type f -name '*.jpg' -exec du -ch {} + | grep total$
2
lbo

もう一つは

ls -al <directory> | awk '{t+=$5}END{print t}}'

あなたが単一のディレクトリを探していると仮定します。現在のディレクトリとその下を見たい場合

ls -Ral <directory> | awk '{t+=$5}END{print t}}'
0
chris bird

これは私のために働いたものです。

find -type f -iname *.jpg -print0 | du -ch --files0-from=- | grep total$
0
serendrewpity

Duではなくstatを使用する他の代替手段

stat -L -c %s ** | awk '{s+=$1} END {printf "%.0f\n", s}'

**の使用に関するGillesの回答をご覧ください

0
Peter Frost