実際のディレクトリサイズを取得するにはどうすればよいですか?


17

UNIX / Linux標準ツールを使用して、実際のディレクトリサイズを取得するにはどうすればよいですか?

代替の質問:どのように私は入手できますかデュ私の実際のディレクトリサイズ(ないディスク使用量)を表示するには?

「サイズ」という用語の定義が異なるように見えるため、「ディレクトリサイズ」の定義は、そのディレクトリ内のすべての通常ファイルの合計です。

ディレクトリiノードのサイズや、ファイルがそれぞれのファイルシステムで占有するもの(ブロック*ブロックサイズ)は気にしません。3ファイル(各1バイト)のディレクトリのディレクトリサイズは3バイトです(私の定義では)。

duを使用したディレクトリサイズの計算は信頼できないようです。
たとえばmkdir foo && du -b foo、0バイトではなく4096バイトの「4096 foo」を報告します。非常に大きなディレクトリの場合、レポートされるディレクトリサイズはdu -hs100 GB(!)以上(圧縮ファイルシステム)になる場合があります。

それでは、実際のディレクトリサイズを取得するために使用する必要があるのは何ですか(ツール/オプション)?


新しい場所でどのファイルシステムが使用されていxfsますか?
セルゲイヴラソフ


また、新しいFSが実際にXFSである場合、ディスク使用量が大幅に増加するのは、ディスク使用量を犠牲にしてファイルの断片化を減らす積極的な事前割り当てが原因である可能があります。
セルゲイVlasov

回答:


8

Unix標準ツール(POSIX)を使用して人間が読めるディレクトリサイズを表示するスクリプトを次に示します。

#!/bin/sh
find ${1:-.} -type f -exec ls -lnq {} \+ | awk '
BEGIN {sum=0} # initialization for clarity and safety
function pp() {
  u="+Ki+Mi+Gi+Ti+Pi+Ei";
  split(u,unit,"+");
  v=sum;
  for(i=1;i<7;i++) {
    if(v<1024) break;
    v/=1024;
  }
  printf("%.3f %sB\n", v, unit[i]);
}
{sum+=$5}
END{pp()}'

例えば:

$ ds ~        
72.891 GiB

そして今、私はlsここで提案されたすべての呼び出しに欠けている別のオプションを見つけました:-q。このオプションを使用しないと、ファイル名に改行文字が含まれていると、スクリプトが中断します。本当に信頼できるシェルスクリプトを書くのは難しすぎる…
セルゲイヴラソフ

@SergeyVlasov私が投稿したスクリプトは、このようなファイルで壊れてはならず、単に余分な行を無視するだけです。慎重に作成されたファイルに、数値を含む5番目のコロンを含む余分な行がある場合、唯一の問題が発生します。あなたの提案は確かにそのような状況を避けます。ヒントをありがとう、スクリプトが更新されました。
-jlliagre

優れた答え。+1をあなたに
愛hime

これは最も信頼できるソリューションの1つです。スペースまたは引用符が含まれるファイル名で動作し、人間が読めるサイズを出力します。
-basic6

@KIAazeコードをレビューして修正してくれてありがとう!
jlliagre

8

一部のバージョンでは、ディスク使用量の代わりに見かけのサイズを表示duする引数--apparent-sizeをサポートしています。したがって、コマンドは次のようになります。

du -hs --apparent-size

Ubuntu 12.04 LTSに含まれているduのmanページから:

--apparent-size
      print apparent sizes,  rather  than  disk  usage;  although  the
      apparent  size is usually smaller, it may be larger due to holes
      in (`sparse') files, internal  fragmentation,  indirect  blocks,
      and the like

1
動作しません:空のdirsのためのスペースを報告します
カールフォー14

1
これは私のために働いた。
connorbode 14年

2
異なるファイルシステム上のディレクトリを比較する場合、サイズが大幅に異なります。たとえば、同じフォルダーのサイズはzfsファイルシステムでは290Gb、exFatでは324Gbです。上記のソリューションは同じサイズを提供します。
Pixus.ru

4

ただの代替手段ls

ls -nR | grep -v '^d' | awk '{total += $5} END {print total, "Total"}'

ls -nR:に-n似て-lいますが、数値UIDとGIDを-Rリストし、サブディレクトリを再帰的にリストします 。

grep -v:一致しないラインを選択するには、一致の感覚を反転します。(-vはPOSIXで指定されます。)。'^ d'ディレクトリを除外します。

Lsコマンド:http : //linux.about.com/od/commands/l/blcmdl1_ls.htm

Man Grep:http : //linux.die.net/man/1/grep

編集

@ Sergey Vlasovの提案として編集。


(名前の代わりにUID / GID番号を表示-nする)のls代わりにオプションを使用する-lと、ユーザー名とグループ名にスペースを含めることができるため、安全です(たとえば、winbindまたはsssdシステムをWindowsドメインに参加させる場合、グループ名を取得できますdomain users) 。また、ユーザー名とグループ名を検索する必要がないため、高速になります。
セルゲイヴラソフ

おかげで、これはfind -exec lsよりもはるかに高速です!
gpothier

4

duGNU coreutils を使用していると仮定すると、このコマンドは、ファイル数の任意の制限なしに、ディレクトリ内の任意の数の通常ファイルの合計見かけのサイズを計算する必要があります。

find . -type f -print0 | du -scb --files0-from=- | tail -n 1

内部にハードリンクファイルがいくつかあり、各ハードリンクを個別にカウント-lするdu場合にオプションを追加します(デフォルトでduは、複数のハードリンクを一度だけカウントします)。

プレーンdu -sbとの最も重要な違いは、再帰duはディレクトリのサイズもカウントすることです。これは、異なるファイルシステムによって異なる方法で報告されます。これを回避するには、findコマンドを使用して通常のファイルのみをに渡しますdu。もう1つの違いは、シンボリックリンクが無視されることです(それらをカウントする必要がある場合は、findコマンドを調整する必要があります)。

また、このコマンドは、プレーンよりも多くのメモリを消費しますdu -sb使用しているので、--files0-from=FILE可能du店舗のデバイスとのiノード番号をすべて処理されたファイルを複数のハードリンクを持つファイルだけを覚えるのデフォルトの動作とは反対に、。(-lデバイスおよびiノード番号を保存する唯一の理由は、すでに処理されたハードリンクファイルをスキップすることであるため、このオプションを使用してハードリンクを複数回カウントする場合、これは問題になりません。)

人間が読める合計サイズの表現を取得したい場合は、-hオプションを追加するだけです(du他の推奨される回答とは異なり、これは1回だけ呼び出され、合計サイズ自体を計算するためです)。

find . -type f -print0 | du -scbh --files0-from=- | tail -n 1

または(の一部の効果が-bによってオーバーライドされることが心配な場合-h

find . -type f -print0 | du -sc --apparent-size -h --files0-from=- | tail -n 1

FreeBSDで何をすべきかわからない- -bおそらくに置き換えることができます-A -B 1が、に相当するものはなく、ファイルリストが(および人間が読める出力用の外部ソリューション)よりも大きい場合は--files0-from=-、使用xargsにいくつかの回避策が必要ARG_MAXです。
セルゲイヴラソフ

3

必要なのがファイルのサイズだけで、ディレクトリが占有するスペースを除く場合は、次のようなことを行うことができます

find . -type f -print0 | xargs -0 du -scb | tail -n 1

@SergeyVlasovは、を超えるファイルがある場合、これは失敗することを指摘しましたargmax。それを回避するには、次のようなものを使用できます。

find . -type f -exec du -sb '{}' \; | gawk '{k+=$1}END{print k}'

1
ディレクトリは、彼らが)(はexecve上の制限で引数のサイズに合わないことを非常に多くのファイルが含まれている場合、このコマンドは黙って間違った結果が得られます-この場合にはxargs起動しますdu複数回、各呼び出しはちょうどその部分の総計を印刷します完全なファイルリストtailの最後の部分の合計サイズのみが表示されます。
セルゲイヴラソフ

1
@SergeyVlasov良い点、私はそれを考えていませんでした、ありがとう、答えが更新されました。
テルドン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.