各ディレクトリ内の最大のファイルを再帰的に検索したい

各ディレクトリ内の最大のファイルを再帰的に検索したい

出力には、ディレクトリ名、ファイル名、ファイル サイズが含まれます。コマンドが実行されるディレクトリごとに 1 つ (最大のファイル) あります。

可能であれば、そのディレクトリ内のファイルの平均サイズも。

目的は、ディレクトリ内の他のファイルよりもはるかに大きいファイルを探して、それらを置き換えることです。

答え1

GNU findsortおよびsed(4.2.2 以上) では、ファイル サイズで一度ソートし、ディレクトリ パスでもう一度ソートします。

find /some/dir -type f -printf '%s %f%h\0' | 
  sort -zrn |
  sort -zut/ -k2 |
  sed -zre 's: ([^/]*)(/.*): \2/\1:'

説明:

  • ファイルのサイズ、名前、パスが出力され (最初の 1 つはスペースで区切られ、次の 2 つは で区切られます/)、各エントリは ASCII NUL 文字で終了します。
  • 次に、NUL で区切られた出力を想定して、サイズを使用して数値的にソートします (逆順、つまり最大のファイルが最初になります)。
  • 次に、 2 番目の で区切られたフィールド (ファイルを含むディレクトリへのパス) のsortすべてを使用して、最初の一意のエントリのみを印刷します。/
  • 次に、sedディレクトリとファイル名を交換して、通常のパスを取得します。

読みやすい出力にするには、ASCII NUL を改行に置き換えます。

find /some/dir -type f -printf '%s %f%h\0' | 
  sort -zrn |
  sort -zut/ -k2 |
  sed -zre 's: ([^/]*)(/.*): \2/\1:' |
  tr '\0' '\n'

出力例:

$ find /var/log -type f -printf '%s %f%h\0' | sort -zrn | sort -zt/ -uk2 | sed -zre 's: ([^/]*)(/.*): \2/\1:' | tr '\0' '\n'
3090885 /var/log/syslog.1
39789 /var/log/apt/term.log
3968 /var/log/cups/access_log.1
31 /var/log/fsck/checkroot
467020 /var/log/installer/initial-status.gz
44636 /var/log/lightdm/seat0-greeter.log
15149 /var/log/lxd/lxd.log
4932 /var/log/snort/snort.log
3232 /var/log/unattended-upgrades/unattended-upgrades-dpkg.log

答え2

と を組み合わせるfindと、awk平均値も計算できます。

find . -type f -printf '%s %h/%f\0'|awk 'BEGIN { RS="\0" } { SIZE=$1; for (i = 1; i <= NF - 1; i++) $i = $(i + 1); NF = NF - 1; DIR=$0; gsub("/[^/]+$", "", DIR); FILE=substr($0, length(DIR) + 2); SUMSIZES[DIR] += SIZE; NBFILES[DIR]++; if (SIZE > MAXSIZE[DIR] || !BIGGESTFILE[DIR]) { MAXSIZE[DIR] = SIZE; BIGGESTFILE[DIR] = FILE } }; END { for (DIR in SUMSIZES) { printf "%s: average %f, biggest file %s %d\n", DIR, SUMSIZES[DIR] / NBFILES[DIR], BIGGESTFILE[DIR], MAXSIZE[DIR] } }'

より読みやすいレイアウトのAWKスクリプトは

BEGIN { RS="\0" }

{
  SIZE=$1
  for (i = 1; i <= NF - 1; i++) $i = $(i + 1)
  NF = NF - 1
  DIR=$0
  gsub("/[^/]+$", "", DIR)
  FILE=substr($0, length(DIR) + 2)
  SUMSIZES[DIR] += SIZE
  NBFILES[DIR]++
  if (SIZE > MAXSIZE[DIR] || !BIGGESTFILE[DIR]) {
    MAXSIZE[DIR] = SIZE
    BIGGESTFILE[DIR] = FILE
  }
}

END {
  for (DIR in SUMSIZES) {
    printf "%s: average %f, biggest file %s %d\n", DIR, SUMSIZES[DIR] / NBFILES[DIR], BIGGESTFILE[DIR], MAXSIZE[DIR]
  }
}

これはヌルで区切られた入力レコードを想定しています(これはmuruの答え); 入力レコードごとに、

  • サイズを保存する(後で使用するため)
  • パスの最初の文字より前のすべてを削除します(少なくともスペースを含むファイル名を正しく処理します)。
  • ディレクトリを抽出し、
  • ファイル名を抽出し、
  • 先ほど保存したサイズをディレクトリ内のサイズの合計に追加します。
  • ディレクトリ内のファイル数を増やす(平均を計算できるようにするため)、
  • サイズがディレクトリに保存されている最大サイズより大きい場合、またはディレクトリ内にまだファイルが存在しない場合は、最大のファイルの情報を更新します。

すべてが完了すると、スクリプトはキーをループしSUMSIZES、ディレクトリ、平均サイズ、最大ファイルの名前とサイズを出力します。

出力をパイプしてディレクトリ名でソートすることができます。サイズを人間に分かりやすい形式でさらにフォーマットしたい場合は、行を次のようにsort変更します。printf

printf "%.2f %d %s: %s\n", SUMSIZES[DIR] / NBFILES[DIR], MAXSIZE[DIR], DIR, BIGGESTFILE[DIR]

そして、出力を にパイプしますnumfmt --field=1,2 --to=iec。ディレクトリ名で結果を並べ替えることもできますが、3 番目のフィールドから並べ替えを開始する必要がありますsort -k3

答え3

ズッシュワイルドカードパターンあなたがやっているようなことにとても役立つでしょう。具体的には、zshは、タイプ、サイズなどの属性でファイルを一致させることができます。glob 修飾子Glob 修飾子を使用すると、一致を並べ替えることもできます。

たとえば、zsh では、*(.DOLN[1])現在のディレクトリにある最大のファイルの名前に展開されます。は*ファイル名のパターンです (シェル オプションに応じてドット ファイルを除くすべてに一致します)。修飾子は、.一致を通常のファイルに制限し、ドット ファイルを組み込み、サイズ (「長さ」) の降順で並べ替え、D一致するファイルがまったくない場合は展開を空にして、最初の一致のみを選択します。*OLN[1]

を使用してディレクトリを再帰的に列挙することができます**/。たとえば、次のループは、現在のディレクトリのすべてのサブディレクトリとそのサブディレクトリを再帰的に反復します。

for d in **/*(/); do … done

使用できますzstat解析のために他のツールに頼ることなく、ファイルのサイズやその他のメタデータにアクセスできます。

zmodload -F zsh/stat b:zstat
files=(*(DNoL))
zstat -A sizes +size -- $files
total=0; for s in $sizes; do total+=$s; done
if ((#sizes > 0)); then
  max=$sizes[-1]
  average=$((total/#sizes))
  median=$sizes[$((#sizes/2))]
fi

答え4

baobab または類似のソフトウェアの使用を検討してください。おそらく、ディストリビューションに 1 つ以上のソフトウェアが含まれています。これらのソフトウェアは、問題のあるディレクトリを非常にわかりやすく視覚化します。

  • バオバブ
  • JDiskレポート
  • NCDU
  • K4DirStat
  • QDirStat
  • GDマップ

http://alternativeto.net/software/baobab/?platform=linux

そして、baobab のマニュアルページにはそれがどのようになっているかが書かれています。

$> man baobab
BAOBAB(1)

NAME
       Baobab - A graphical tool to analyse disk usage

SYNOPSIS
       baobab  [directory]

DESCRIPTION
       baobab is able to scan either specific folders or the whole filesys-
       tem (local and remote), in order to give the user a graphical tree
       representation including each directory size or percentage in the
       branch.  It also auto-detects in real-time any change made to your
       home directory as far as any mounted/unmounted device. A graphical
       treemap window is also provided for any selected folder.

       A detailed documentation on the program could be read at:
       http://www.gnome.org/projects/baobab

AUTHOR
       Fabio MARZOCCA <[email protected]>



                                                                     BAOBAB(1)

関連情報