web-dev-qa-db-ja.com

ディレクトリリストにファイルサイズの合計を表示する

Windowsのdirディレクトリ一覧コマンドの最後には、一覧表示されたファイルが占める総容量を示す行があります。たとえば、dir *.exeは、現在のディレクトリにあるすべての.exeファイル、それらのサイズ、およびそれらのサイズの合計を示します。 bashでdirエイリアスを使用して同様の機能を実現したいのですが、どうすればよいかわかりません。

現在、alias dir='ls -FaGl'.bash_profileにあり、

drwxr-x---+  24 mattdmo  4096 Mar 14 16:35 ./
drwxr-x--x. 256 root    12288 Apr  8 21:29 ../
-rw-------    1 mattdmo 13795 Apr  4 17:52 .bash_history
-rw-r--r--    1 mattdmo    18 May 10  2012 .bash_logout
-rw-r--r--    1 mattdmo   395 Dec  9 17:33 .bash_profile
-rw-r--r--    1 mattdmo   176 May 10  2012 .bash_profile~
-rw-r--r--    1 mattdmo   411 Dec  9 17:33 .bashrc
-rw-r--r--    1 mattdmo   124 May 10  2012 .bashrc~
drwx------    2 mattdmo  4096 Mar 24 20:03 bin/
drwxrwxr-x    2 mattdmo  4096 Mar 11 16:29 download/

例えば。 この質問 から回答を受け取る:

dir | awk '{ total += $4 }; END { print total }'

合計は表示されますが、ディレクトリリスト自体は出力されません。これをワンライナーまたはシェルスクリプトに変更して、ls引数を渡してdirを渡し、完全なリストと合計を取得する方法はありますか?たとえば、dir -R *.jpg *.tifを実行して、すべてのサブディレクトリにあるファイルタイプのリストと合計サイズを取得します。各サブディレクトリのサイズを取得できれば理想的ですが、これは必須ではありません。

82
MattDMo

次の関数は、あなたが求めているほとんどのことを行います:

dir () { ls -FaGl "${@}" | awk '{ total += $4; print }; END { print total }'; }

...しかしdir -R *.jpg *.tifの機能ではないため、ls -Rから求めているものが得られません。 find ユーティリティを試してみてください。

26
user27282

これにはすでにUNIXコマンドがあります:du

ただやる:

du -ach 

慣例に従って、コマンドの最後に1つ以上のファイルまたはディレクトリパスを追加できます。 -hは、サイズを人にわかりやすい形式に変換する拡張機能です-aは、「見かけの」サイズ(ディスク使用量ではなくファイルサイズ)を提供し、-cは、最後に合計を示します。

168
Pete Cornell

du -h -c directory|tail -1を使用できます

これにより、メモリ使用量を含む1行が生成されます。

23
mani deepak

次の合計を合計している現在の行を印刷するだけです。

dir | awk '{ print; total += $4 }; END { print "total size: ",total }'
8
Mauritz Hansen

perlの場合:

Perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf

現在のディレクトリにあるすべての非表示でないファイルのサイズPDFファイル。

6
ingopingo

以下を.bash_profileまたは.bashrcに追加するとうまくいきます。

dir ()
{
find . -iname "$@" -exec ls -lh {} \;
find . -iname "$@" -print0|xargs -r0 du -csh|tail -n 1;
}

Dir * .mp3を実行すると、再帰的に実行され、最後に合計が出力されます。検索にmaxdepthパラメータを追加することで、必要な深度を制御できます。 findを2回実行することは、非常に効率的なアイデアではありません。しかし、私はもっと良い方法を考えることができませんでした。少なくともそれは仕事を成し遂げる。

1
bagavadhar

上記のようなdおよびawkステートメントを使用すると、探しているものが提供されます。

例:du /home/abc/Downloads/*.jpg | awk '{ print; total += $1 }; END { print "total size: ",total }'

これにより、.jpgで終わるユーザーabcのフォルダーDownloadsにあるすべてのファイルがリストされ、リストの最後にこれらのすべてのファイルの合計が印刷されます。

1
user3085123
du path_to_your_files/*.jpg | awk '{ total += $1 }; END { print total }'
0
Tamer Mansour

マスクを使用してディレクトリ内のファイルをカウントするために、私はこのアプローチに従う傾向があります:

バイトの場合

du -ac --bytes  | grep "Zip$" | awk '{ print; total += $1 }; END { print "total lobsters: ", total, " Bytes" }'

キロバイトの場合

du -ac --bytes  | grep "Zip$" | awk '{ print; total += $1 }; END { print "total lobsters: ", total/1024, " KB" }'

メガバイトの場合

du -ac --bytes  | grep "Zip$" | awk '{ print; total += $1 }; END { print "total lobsters: " total/1024/1024 " MB" }'

あなたはアイデアを得ます。

内訳は簡単です:

  • d -ディスク使用量
    • -a-すべてのファイル
    • -c-合計バイト
    • --bytes-出力をバイト単位で出力します[新しいバージョンのbashでは、これが適用されるかどうか不明です]
  • grep -g lobal r egular e xpression p rint [一致する出力パターンを出力する]
    • 「Zip $」-一致するパターン。 'Zip'は文字列で、 '$'は文字列/行/などの終わりを示します。この場合、[〜#〜] end [〜#〜] 'Zip'を使用します。逆に、文字列の先頭に「^」を置くと、パターンが文字列の先頭にあることを示します[つまり、「^ start」は、行で始まる 'start']-この知識により、文字列をそれぞれ^および$でラップすると、使用されるパターンで開始/終了する行に一致します。 「^ hello people $」は、「hello people」という文字列に一致します。 "^ hello(。*)people $"は、「hello french people」および「hellocoding people」という文字列に一致しますが、ではありません
  • awk - [〜#〜] a [〜#〜] ho によってプログラムされたスクリプト言語 [ 〜#〜] w [〜#〜] einberger 、および [〜#〜] k [〜#〜] ernighan 。あまり元の名前ではありませんが、テキスト処理やデータ抽出に優れた非常に強力な言語です。
    • {印刷;合計+ = $ 1}
      • print-現在反復されている行を印刷します
      • 合計+ = $ 1-変数totalをまだ初期化していない場合は初期化し、field separatorで区切られた最初のブロック、この場合はspace characterを追加します。これは-Fフラグで変更できます。
      • ; -行/ステートメントのターミネーター。これを使用して、Linuxコマンドラインステートメントを終了するのと同様に、複数のawkステートメントを1行に配置できます。それ以外の場合は、それらを{...}で囲まれた複数行のものにすることができます。
      • END-これは事実上、awkが終了する前に指定されたアクションを実行することを意味します。
    • {「ロブスターの合計数:」「合計「バイト」}を出力する}
      • 「全ロブスター数:」を出力する-出力される文字列の最初の部分
      • total-反復された行の合計を含む変数
      • "Bytes"-印刷された文字列の最後の部分。前の2つのステートメントの最後に追加されます
      • 明らかに、これらの3つのステートメントは、最初の部分と同様に{}でカプセル化されています。

したがって、ディレクトリ内のZipファイルの総数をカウントする場合の例をステップ実行します。

du -ac --bytes

836544  ./wp-content/themes/astra.1.8.1.Zip
934364  ./wp-content/themes/astra.2.0.1.Zip
400033  ./wp-content/uploads/2019/09/premium-addons-for-elementor-3.2.9-WJdFQT1mLd3GA81lQEAo.Zip
117351218       ./wp-content/uploads/backwpup-fc5928-temp/2019-05-30_00-47-01_TX6FSKC601.Zip
1192275 ./wp-content/plugins/essential-addons-elementor-master.Zip
170     ./wp-content/plugins/gravityforms/images/doctypes/icon_Zip.gif
1969651 ./wp-content/plugins/acf.Zip
4284    ./wp-content/plugins/types/application/controllers/api/handler/import_from_Zip_file.php

出力の2つのコンポーネント、col 1数値で表されます:836544、934364 ...など、および col 2はファイルのパスです。

ただし、必要な行と一致しない行が2つあるため、icon_Zip.gifimport_from_Zip_file.phpを除外します。 duは、(私が知っている)拡張によって再帰的にフィルタリングする方法を提供しないため、grepを使用してフィルタリングします

grep "Zip$"

これにより、duからの出力がパイプラインされ、Zipで終わる行がフィルター処理されて、2つのレコードが削除されます。欲しくない:

836544  ./wp-content/themes/astra.1.8.1.Zip
934364  ./wp-content/themes/astra.2.0.1.Zip
400033  ./wp-content/uploads/2019/09/premium-addons-for-elementor-3.2.9-WJdFQT1mLd3GA81lQEAo.Zip
117351218       ./wp-content/uploads/backwpup-fc5928-temp/2019-05-30_00-47-01_TX6FSKC601.Zip
1192275 ./wp-content/plugins/essential-addons-elementor-master.Zip
1969651 ./wp-content/plugins/acf.Zip

次に、awkは各行を解析し、col 1の数値は$1に格納されます

私たちはこれを得ます:

836544  ./wp-content/themes/astra.1.8.1.Zip
934364  ./wp-content/themes/astra.2.0.1.Zip
400033  ./wp-content/uploads/2019/09/premium-addons-for-elementor-3.2.9-WJdFQT1mLd3GA81lQEAo.Zip
117351218       ./wp-content/uploads/backwpup-fc5928-temp/2019-05-30_00-47-01_TX6FSKC601.Zip
1192275 ./wp-content/plugins/essential-addons-elementor-master.Zip
1969651 ./wp-content/plugins/acf.Zip
total lobsters:  128.339  MB
0
Barry Chapman

他の提案されたオプションを使用せずに、dir出力とサイズ計算の両方を取得するには、tee(1)とプロセス置換を使用できます...

dir | tee >( awk '{ total += $4 }; END { print total }' )
0
Janis