web-dev-qa-db-ja.com

Linuxで、名前が正規表現と一致するファイルのディスク使用量?

そのため、多くの状況で、ディスク領域の何が何によって使用されているかを知る方法が必要だったので、何を取り除くか、別のフォーマットに変換するか、他の場所(データDVDなど)に保存するか、別のパーティションに移動するかを知っています。この場合、私は SliTaz Linux ブータブルメディアからWindowsパーティションを見ています。

ほとんどの場合、必要なのはファイルとフォルダーのサイズであり、そのためにNCursesベースの ncd を使用します。

ncdu

しかし、この場合、正規表現に一致するすべてのファイルのサイズを取得する方法が必要です。 .bakファイルの正規表現の例:

.*\.bak$

コアGNUユーティリティまたは BusyBox を備えた標準のLinuxを考えて、どうすればその情報を取得できますか?

編集:出力は、スクリプトで解析できるようになっています。

39
Camilo Martin

私は次のようなものを提案します:find . -regex '.*\.bak' -print0 | du --files0-from=- -ch | tail -1

いくつかのメモ:

  • -print0オプションfindおよび--files0-from for duは、ファイル名の空白に関する問題を回避するためにあります
  • 正規表現はパス全体と照合されます。 ./dir1/subdir2/file.bak、 だけでなく file.bak、変更する場合は考慮に入れてください
  • Duにhフラグを使用して「人間が読める」形式を生成しましたが、出力を解析したい場合は、kを使用することをお勧めします(常にキロバイトを使用)
  • tailコマンドを削除すると、特定のファイルとディレクトリのサイズがさらに表示されます

補足:ディスクスペースを誰が食べたかを知るための素晴らしいGUIツールは FileLight です。正規表現は行いませんが、ディスクを詰まらせる大きなディレクトリやファイルを見つけるのに非常に便利です。

47

duが私のお気に入りの答えです。ファイルシステム構造が固定されている場合は、以下を使用できます。

du -hc *.bak

サブディレクトリを追加する必要がある場合は、以下を追加します。

du -hc *.bak **/*.bak **/**/*.bak

などなど

ただし、これはあまり便利なコマンドではないため、検索を使用します。

TOTAL=0;for I in $(find . -name \*.bak); do  TOTAL=$((TOTAL+$(du $I | awk '{print $1}'))); done; echo $TOTAL

これにより、見つかったすべてのファイルの合計サイズがバイト単位で表示されます。

お役に立てば幸いです。

25
MaddHacker

以前の解決策は私には適切に機能しませんでした(duのパイピングに問題がありました)が、以下はうまく機能しました:

find path/to/directory -iregex ".*\.bak$" -exec du -csh '{}' + | tail -1

iregexオプションは、大文字と小文字を区別しない正規表現です。大文字と小文字を区別する場合は、regexを使用します。

正規表現に慣れていない場合は、inameまたはnameフラグを使用できます(前者は大文字と小文字を区別しません)。

find path/to/directory -iname "*.bak" -exec du -csh '{}' + | tail -1

すべての一致のサイズが必要な場合(単に合計した合計ではなく)、パイプで接続されたテールコマンドを省略します。

find path/to/directory -iname "*.bak" -exec du -csh '{}' +

これらのアプローチにより、@ MaddHackersの回答のサブディレクトリの問題が回避されます。

これが同じ状況で他の人に役立つことを願っています(私の場合、.NETソリューションですべてのDLLのサイズを見つける)。

3
ben.snape

これをボーンシェルで実行して、現在のディレクトリの正規表現パターンに一致するすべてのファイルのサイズの合計を計算する関数を宣言します。

_sizeofregex() { IFS=$'\n'; for x in $(find . -regex "$1" 2> /dev/null); do du -sk "$x" | cut -f1; done | awk '{s+=$1} END {print s}' | sed 's/^$/0/'; unset IFS; }
_

(または、スクリプトに入れることもできます。)

使用法:

_cd /where/to/look
sizeofregex 'myregex'
_

結果は_0_を含む(KiB単位の)数値になります(正規表現に一致するファイルがない場合)。

_.so_のマウントである_/_の下にあるが、__(SOMECODE)の下ではなく、すべての_/dev/sda1_ファイルを_/home_の下で検索したい場合__、これは_/dev/sdb1_のマウントです。上記の関数のfindに_-xdev_パラメータを追加します。

3
Camilo Martin

Glob-patternsに問題がなく、現在のディレクトリのみに関心がある場合:

stat -c "%s" *.bak | awk '{sum += $1} END {print sum}'

または

sum=0
while read size; do (( sum += size )); done < <(stat -c "%s" *.bak)
echo $sum

Statへの%sディレクティブはキロバイトではなくバイトを与えます。

Bashバージョン4を使用してサブディレクトリに移動する場合は、shopt -s globstarを使用してパターン**/*.bakを使用できます。

1
glenn jackman

受け入れられた応答は使用することを提案します

_find . -regex '.*\.bak' -print0 | du --files0-from=- -ch | tail -1
_

しかし、duが私のシステムの_--files-0-from_オプションを認識していないため、これは私のシステムでは機能しません。 GNU duはそのオプションを知っていますが、それは POSIX標準 の一部ではありません(そのため、FreeBSDやmacOSでは見つかりません)。 BusyBoxベースのLinuxシステム (たとえば、ほとんどの組み込みLinuxシステム)またはGNU duバージョンを使用しないその他のLinuxシステム。

次に、使用を提案する返信があります:

_find path/to/directory -iregex .*\.bak$ -exec du -csh '{}' + | tail -1
_

_+_はfindが単一の呼び出しでできるだけ多くのヒットでduを呼び出そうとするため、この解決策はファイルがあまり多くない限り機能しますが、引数の最大数がある場合があります。 (N)システムがサポートし、この値より多くのヒットがある場合、findduを複数回呼び出し、ヒットをそれぞれNアイテム以下のグループに分割します。この場合、結果は正しくなく、サイズのみが表示されます。最後のdu呼び出し。

最後に、statawkを使用した答えがあります。これは良い方法ですが、Bash 4.x以降のみがサポートする方法でシェルグロビングに依存しています。古いバージョンでは動作せず、他のシェルで動作するかどうかは予測できません。

POSIX準拠のソリューション(Linux、macOS、およびBSDバリアントで動作します)であり、制限の影響を受けず、すべてのシェルで確実に動作します。

_find . -regex '.*\.bak' -exec stat -f "%z" {} \; | awk '{s += $1} END {print s}'
_
1
Mecki