du -h出力をサイズでソートするにはどうすればよいですか


966

人間が読めるdu出力のリストを取得する必要があります。

ただし、du「サイズによる並べ替え」オプションsortはなく、パイピングは人間が読めるフラグでは機能しません。

たとえば、次を実行します。

du | sort -n -r 

サイズ別にソートされたディスク使用量を出力します(降順):

du |sort -n -r
65108   .
61508   ./dir3
2056    ./dir4
1032    ./dir1
508     ./dir2

ただし、人間が読めるフラグで実行すると、適切にソートされません。

du -h | sort -n -r

508K    ./dir2
64M     .
61M     ./dir3
2.1M    ./dir4
1.1M    ./dir1

誰でもdu -h サイズでソートする方法を知っていますか?


へえ...おかしい、これは私を悩ませているので...少なくとも1年以上。先週、GNU coreutils(この種類は一部です)にコードをダウンロードして見てみましたが、パッチを当てるのに手がかかるよりも少し時間がかかると決めました... :)
解く

:ここでは多くの関連質問だserverfault.com/q/737537/35034
cregox

これを見た? unix.stackexchange.com/questions/4681/… これはほぼ重複しており、ゴールドの価値があります。通常は実行しますduが、sortコマンドに-hを追加します。-rhファイル内で最大のものが最初になるように追加できます。そうでない場合tailは、スペースの占有を確認する必要があります。
SDsolar

私がこれをグーグルで検索したとき、私はそのような質問がそれほど人気が​​あるとは思わなかった。
Mateen Ulhaq

回答:


1362

2009年8月にリリースされたGNU coreutils 7.5の時点でsort-hパラメーターによって許可されdu -hます。

du -hs * | sort -h

をサポートしないソートを使用している場合は-h、GNU Coreutilsをインストールできます。たとえば、古いMac OS Xの場合:

brew install coreutils
du -hs * | gsort -h

sort マニュアルから:

-h, --human-numeric-sort compare human readable numbers (e.g., 2K 1G)


3
マニュアルの関連セクション:gnu.org/software/coreutils/manual/...
wodow

29
homebrewでOS Xに簡単にインストールできます-brew install coreutils。
リチャードポワリエ

41
いいね!私は個人的には常にdu -BM | sort -nr回避策として行った-それは人間が読めるほど十分であり、誰かが古いcoreutilsで立ち往生している場合はソートされている。
チャッツ

30
自作を通じてOSX上で使用している場合、あなたは今の並べ替えではなくgsort使用する必要がありますのでご注意:du -hs * | gsort -h
ブライアン・クライン

2
@PaulDraperは、du -BMすべてをメガバイト単位で印刷するため、168Kのファイルは実際には0Mと表示されます。他のバージョンの矛盾がない限り、私は知りません。私のバージョンでduは、整数メガバイトの値のみが表示されます。
chutz 14

88
du | sort -nr | cut -f2- | xargs du -hs

48
そして、膨大な量の重複カウントを行います。
ダグラスリーダー2009

1
最初に通常のduを実行します。次に、エントリごとにサイズを再計算して、人間が読める形式で印刷します。
ダグラスリーダー2009

8
@Douglas Leeder:あなたは重複カウントには正しいですが、2番目のduはコールドキャッシュから始まっていないと思います(OSのおかげです)@hasen j:xargsは非常に便利なコマンドであり、stdinを分割して引数として供給します与えられたコマンド
カドリアン09

4
クリスは空白を含むパスで動作するため、実際には優れています。投票してください、バディ。
rbright 09

3
glyいですが、クロスプラットフォーム:)。
voretaq7

62

@Douglas Leeder、もう1つの答え:別のツールを使用してdu -hから人間が読める出力をソートします。Perlのように!

du -h | perl -e 'sub h{%h=(K=>10,M=>20,G=>30);($n,$u)=shift=~/([0-9.]+)(\D)/;
return $n*2**$h{$u}}print sort{h($b)<=>h($a)}<>;'

ディスプレイに合わせて2行に分割します。この方法で使用するか、ワンライナーにすることができます。どちらの方法でも機能します。

出力:

4.5M    .
3.7M    ./colors
372K    ./plugin
128K    ./autoload
100K    ./doc
100K    ./syntax

編集:PerlMonksでゴルフを数ラウンド行った後、最終結果は次のようになります。

perl -e'%h=map{/.\s/;99**(ord$&&7)-$`,$_}`du -h`;die@h{sort%h}'

2
あなたのショートバージョンstderrは、dieあなたがそれを出力するように変更できるので、出力しstdoutますか?
デニスウィリアムソン

2
をに変更dieするprintと、に移動しstdoutます。あと2文字です。
アダムベレール

Ubuntuで動作します!
マリナーラ

印象的なPerlのhackistry
nandoP

結果は逆順です:(
RSFalcon7 14

55

私が使用する非常に便利なツールncduは、これらの厄介なディスク使用率の高いフォルダーとファイルを見つけて削除するために設計されています。コンソールベースで高速かつ軽量で、すべての主要なディストリビューションにパッケージがあります。


結果は標準出力に供給することができれば非常に素晴らしい...私はwondier ...私はマニュアルを読まないことができるように怠惰だ
ojblass

8
gt5も同じです。そのキラー機能は成長を見せています。
東武

1
かっこいい!du大きなディレクトリを特定するだけの場合、でぶらぶらするよりもはるかに高速です。
-BurninLeo

44
du -k * | sort -nr | cut -f2 | xargs -d '\n' du -sh

で使用できません。du -k --total最後にエラーが発生しますdu: cannot access 'total': No such file or directory
laggingreflex

私はこれがもう一つの他の答えが好きです。最初の50件の結果のみを表示するにはどうしますか?
マウ

1
@Mauro- head`|を追加して結果をパイプするだけ 最後に-50`。
サミュエルルリエーヴル

21

私が見る限り、あなたには3つのオプションがあります:

  1. アルターdu表示する前にソートします。
  2. 変更しsortた数値の並べ替えのための人間のサイズをサポートします。
  3. sortからの出力を後処理して、基本出力を人間が読める形式に変更します。

またdu -k、KiBでサイズを指定して実行することもできます。

オプション3では、次のスクリプトを使用できます。

#!/usr/bin/env python

import sys
import re

sizeRe = re.compile(r"^(\d+)(.*)$")

for line in sys.stdin.readlines():
    mo = sizeRe.match(line)
    if mo:
        size = int(mo.group(1))
        if size < 1024:
            size = str(size)+"K"
        elif size < 1024 ** 2:
            size = str(size/1024)+"M"
        else:
            size = str(size/(1024 ** 2))+"G"

        print "%s%s"%(size,mo.group(2))
    else:
        print line

20

私もその問題を抱えていて、現在回避策を使用しています:

du -scBM | sort -n

これはスケーリングされた値を生成しませんが、常にメガバイト単位のサイズを生成します。それは完璧ではありませんが、私にとっては何もないよりも優れています(またはサイズをバイト単位で表示する)。


私は基本的には-mと同じである第-bmスイッチを、好きですが、あなただけの10 :)よりもはるかに明確である10Mを取得するので、それはサイズを表示する利点を持っており、Mはそれに後置
トムFeiner

これは私がこのページでこれまで見た中で最も簡単な解決策です、ありがとう!
ジェフオルソン

19

他の場所でこの投稿を見つけました。したがって、このシェルスクリプトはdu、すべてを2回呼び出すことなく、必要な処理を実行します。awk生のバイトを人間が読める形式に変換するために使用します。もちろん、書式設定はわずかに異なります(すべてが小数点以下1桁の精度で印刷されます)。

#/bin/bash
du -B1 | sort -nr  |awk '{sum=$1;
hum[1024**3]="G";hum[1024**2]="M";hum[1024]="K";
for (x=1024**3; x>=1024; x/=1024){
        if (sum>=x) { printf "%.1f%s\t\t",sum/x,hum[x];print $2;break
}}}'

これを私の.vimディレクトリで実行すると:

4.4M            .
3.6M            ./colors
372.0K          ./plugin
128.0K          ./autoload
100.0K          ./syntax
100.0K          ./doc

(3.6Mの配色が過剰ではないことを願っています。)


1
私もPerlの答えを持っていますが、それは人々が私を嫌うようになるかもしれないと思います:du -B1 | sort -nr | perl -e '%h =(0 => b、1 => K、2 => M、3 => G); for(<>){($ s、@ f)= split / \ s + /; $ e = 3; $ e-- while(1024 ** $ e> $ s); $ v =($ s /(1024 ** $ e)); printf "%-8s%s \ n"、sprintf($ v> = 100? "%d%s": "%.1f%s"、$ s /(1024 ** $ e)、$ h {$ e})、@ f;} '
Adam Bellaire

Perlの答えは実際にはそのフォーマットをduにはるかに近づけていますが。丸めはオフですが、デュは常に(切り上げを与えるように...それはむしろラウンドより)になります()
アダムベレア

ねえ、なぜそこでハッシュを使用したのですか?アレイになるべきだった...朝脳の不平不満 ....
アダムベレール

別の答えとして、より良いPerlソリューションを追加しました。
アダムベレール

ファイル名にスペースが含まれていると、両方のバージョンが失敗します
Vi。

15

このバージョンはawk、ソートキー用の追加の列を作成するために使用します。du一度だけ呼び出します。出力はのようになりduます。

複数の行に分割しましたが、1つのライナーに再結合できます。

du -h |
  awk '{printf "%s %08.2f\t%s\n", 
    index("KMG", substr($1, length($1))),
    substr($1, 0, length($1)-1), $0}' |
  sort -r | cut -f2,3

説明:

  • BEGIN-ユニットごとにグループ化するために、K、M、Gを1、2、3に置き換えるインデックスを作成する文字列を作成します。 )
  • 新しいフィールドを印刷します-単位、値(アルファソートを正しく機能させるために、ゼロ詰めで固定長です)および元の行
  • サイズフィールドの最後の文字にインデックスを付けます
  • サイズの数値部分を引き出す
  • 結果をソートし、余分な列を破棄します

cutコマンドなしで試してみて、何をしているかを確認してください。

AWKスクリプト内で並べ替えを行い、必要のないバージョンはcut次のとおりです。

du -h |
   awk '{idx = sprintf("%s %08.2f %s", 
         index("KMG", substr($1, length($1))),
         substr($1, 0, length($1)-1), $0);
         lines[idx] = $0}
    END {c = asorti(lines, sorted);
         for (i = c; i >= 1; i--)
           print lines[sorted[i]]}'

ありがとうございました!これは、perl / phython-scriptsをカウントしないOS X 10.6で機能する最初の例です。良い説明をありがとう。何か新しいことを学ぶのはいつもいいことです。awkは強力なツールです。
オオカミ

それに感謝します。duをに変更して、du -sh *再帰的な降下なしで直接のファイルとディレクトリのみを表示しました。
ハンカ16

15

ディレクトリをよりコンパクトな要約形式で表示する例を次に示します。ディレクトリ/ファイル名のスペースを処理します。

% du -s * | sort -rn | cut -f2- | xargs -d "\n" du -sh

53G  projects
21G  Desktop
7.2G VirtualBox VMs
3.7G db
3.3G SparkleShare
2.2G Dropbox
272M apps
47M  incoming
14M  bin
5.7M rpmbuild
68K  vimdir.tgz

1
macOS / OSXユーザーは、macバージョンのxargsが-dフラグをサポートしていないことに注意してください。これを省略すると、スペースを含むディレクトリの各単語が個別に解析され、もちろん失敗します。
jasonology

11

MB単位のサイズでファイルをソートします

du --block-size=MiB --max-depth=1 path | sort -n

9

私はdutopと呼ばれるシンプルで便利なduのpythonラッパーを持っています。私たち(coreutilsメンテナー)は、「人間」の出力を直接ソートするソート機能を追加することを検討していることに注意してください。


1
「1つのことを行い、正しく実行する」というまれで有効な例外の1つに対して+1。誰かがSIプレフィックスやバイナリプレフィックスを理解するためにソートを取得しない限り。
ヨアヒムザウアー

そして、ptmanが以下に言及しているように:ta da!(新しいsortフラグ)
東武

9

別のものを手に入れました:

$ du -B1 | sort -nr | perl -MNumber::Bytes::Human=format_bytes -F'\t' -lane 'print format_bytes($F[0])."\t".$F[1]'

私はperlが好きになり始めています。あなたがする必要があるかもしれません

$ cpan Number::Bytes::Human

最初。そこにいるすべてのperlハッカーに:はい、perlでもソート部分を実行できることを知っています。おそらくデュパートも。


8

このスニペットは、http://www.unix.com/shell-programming-scripting/32555-du-h-sort.htmlの「Jean-Pierre」から恥知らずに引き抜かれました。私は彼をよりよく信用できる方法がありますか?

du -k | sort -nr | awk '
     BEGIN {
        split("KB,MB,GB,TB", Units, ",");
     }
     {
        u = 1;
        while ($1 >= 1024) {
           $1 = $1 / 1024;
           u += 1
        }
        $1 = sprintf("%.1f %s", $1, Units[u]);
        print $0;
     }
    '

私は、それは非常に大きな数がある場合だと思う、そしてユニットがなくなっていると表示された回数が少ない...試す23423423432423
nopole

7

「-g」フラグを使用します

 -g, --general-numeric-sort
              compare according to general numerical value

そして、私の/ usr / localディレクトリで次のような出力を生成します:

$ du |sort -g

0   ./lib/site_ruby/1.8/rubygems/digest
20  ./lib/site_ruby/1.8/rubygems/ext
20  ./share/xml
24  ./lib/perl
24  ./share/sgml
44  ./lib/site_ruby/1.8/rubygems/package
44  ./share/mime
52  ./share/icons/hicolor
56  ./share/icons
112 ./share/perl/5.10.0/YAML
132 ./lib/site_ruby/1.8/rubygems/commands
132 ./share/man/man3
136 ./share/man
156 ./share/perl/5.10.0
160 ./share/perl
488 ./share
560 ./lib/site_ruby/1.8/rubygems
604 ./lib/site_ruby/1.8
608 ./lib/site_ruby

4
しかし、それは人間が読める出力を提供しません。これはOPが探していたものです。


4

以下は、私が使用する簡単な方法で、リソースの使用量が非常に少なく、必要なものが得られます。

du --max-depth=1 | sort -n | awk 'BEGIN {OFMT = "%.0f"} {print $1/1024,"MB", $2}'

0 MB ./etc
1 MB ./mail
2 MB ./tmp
123 MB ./public_html

4

これをオンラインで見つけました...うまくいくようです

du -sh * | tee /tmp/duout.txt | grep G | sort -rn ; cat /tmp/duout.txt | grep M | sort -rn ; cat /tmp/duout.txt | grep K | sort -rn ; rm /tmp/duout.txt

このワンライナーに大まかに基づいて、人間が読み取れるソート済みのdu(1)出力を提供するスクリプトを作成しました。私の答えserverfault.com/a/937459/218692を参照してください。
トリップキネティクス

3

昨日、この例を作成してawkを学びました。少し時間がかかりましたが、とても楽しかったので、awkの使い方を学びました。

duは1回だけ実行され、du -hに非常に類似した出力があります。

du --max-depth=0 -k * | sort -nr | awk '{ if($1>=1024*1024) {size=$1/1024/1024; unit="G"} else if($1>=1024) {size=$1/1024; unit="M"} else {size=$1; unit="K"}; if(size<10) format="%.1f%s"; else format="%.0f%s"; res=sprintf(format,size,unit); printf "%-8s %s\n",res,$2 }'

10未満の数字と1つの小数点が表示されます。


3

du -cka --max-depth = 1 / var / log | ソート-rn | ヘッド-10 | awk '{print($ 1)/ 1024、 "MB"、$ 2'}


2

スペースを処理する必要がある場合は、次を使用できます

 du -d 1| sort -nr | cut -f2 | sed 's/ /\\ /g' | xargs du -sh

追加のsedステートメントは、Application Supportなどの名前のフォルダーに関する問題を軽減するのに役立ちます


これをmacOS Sierraで試しました。期待どおりに動作します。いいね!
jasonology


1

http://dev.yorhel.nl/ncdu

コマンド:ncdu

ディレクトリナビゲーション、並べ替え(名前とサイズ)、グラフ、人間が読める形式など


1
すばらしいユーティリティですが、私が知っているOSにはデフォルトではインストールされません。...後に見ているために必ずしも問題、しかし、1つの以上のプログラム
voretaq7

1

別のawk解決策-

du -k ./* | sort -nr | 
awk '
{split("KB,MB,GB",size,",");}
{x = 1;while ($1 >= 1024) 
{$1 = $1 / 1024;x = x + 1} $1 = sprintf("%-4.2f%s", $1, size[x]); print $0;}'


[jaypal~/Desktop/Reference]$ du -k ./* | sort -nr | awk '{split("KB,MB,GB",size,",");}{x = 1;while ($1 >= 1024) {$1 = $1 / 1024;x = x + 1} $1 = sprintf("%-4.2f%s", $1, size[x]); print $0;}'
15.92MB ./Personal
13.82MB ./Personal/Docs
2.35MB ./Work Docs
1.59MB ./Work Docs/Work
1.46MB ./Personal/Raa
584.00KB ./scan 1.pdf
544.00KB ./Personal/Resume
44.00KB ./Membership.xlsx
16.00KB ./Membership Transmittal Template.xlsx

1

私は@ptmanが提供するソリューションを使用していましたが、最近のサーバーの変更により、実行不可能になりました。代わりに、次のbashスクリプトを使用しています。

#!/bin/bash
# File: duf.sh
# list contents of the current directory by increasing 
#+size in human readable format

# for some, "-d 1" will be "--maxdepth=1"
du -k -d 1 | sort -g | awk '
{
if($1<1024)
    printf("%.0f KB\t%s",$1,$2);
else if($1<1024*1024)
    printf("%.1f MB\t%s",$1/1024,$2);
else
    printf("%.1f GB\t%s",$1/1024/1024,$2);
}'

du -d 12010年にcoreutils 8.6がリリースされて以来、BSDの構文はGNU duによってサポートされています(その最初のRed Hatは2014年にRHEL 7でしたが)--maxdepth=1。私は最近自分自身でこのことを知りました
アダム・カッツ


1

ここには多くの答えがあり、その多くは重複しています。3つの傾向が見られます。2番目のdu呼び出しのパイプ処理、複雑なシェル/ awkコードの使用、および他の言語の使用。

すべてのシステムで動作するduおよびawkを使用したPOSIX準拠のソリューションを次に示します。

私は少し異なるアプローチを取り-x、同じファイルシステムにとどまるように追加しました(ディスクスペースが不足しているときにのみこの操作が必要になるので、このFSツリー内にマウントしたものや移動したものを取り除く理由シンボリックリンクしますか?)、視覚的な解析を容易にするために一定の単位を表示します。この場合、通常、階層構造をよりよく見ることができるように、ソートしないことを選択します。

sudo du -x | awk '
  $1 > 2^20 { s=$1; $1=""; printf "%7sG%s\n", sprintf("%.2f",s/2^21), $0 }'

(これは一貫した単位であるため、ソートされた結果| sort -nが本当に必要場合は追加できます。)

これにより、(累積)コンテンツが512MBを超えないディレクトリが除外され、サイズがギガバイト単位で表示されます。デフォルトでは、DUは512バイトのブロックサイズを使用して(SO 2つのAWKの条件20ブロックは512メガバイトであり、その2 21 -我々が使用できる除数は、GB単位の変換du -kx$1 > 512*1024し、s/1024^2より人間可読であること)。awk条件の内側で、s行から削除できるようにサイズを設定します($0)。これは区切り文字(単一のスペースに折りたたまれている)を保持するため、final %sはスペースを表し、次に集約されたディレクトリの名前を表します。 %7s丸められた%.2fGBサイズを調整します(%8s10 TBを超える場合に増加)。

ここでのほとんどのソリューションとは異なり、これは名前にスペースを含むディレクトリを適切にサポートします(ただし、これを含むすべてのソリューションは、改行を含むディレクトリ名を誤って処理します)。


0

少なくとも通常のツールでは、人間が判読可能な数字の形式のためにこれは難しいでしょう(数字は508、64、61、2、2-を並べ替えるので、sortはここで「良い仕事」をすることに注意してください)追加の乗数で浮動小数点数を並べ替えることはできません)。

私はそれを他の方法で試してみます-「du | sort -n -r」からの出力を使用し、その後、スクリプトまたはプログラムで数値を人間が読める形式に変換します。


0

あなたが試すことができるのは:

for i in `du -s * | sort -n | cut -f2`
do
  du -h $i;
done

お役に立てば幸いです。


それがxargsが行うことです;-)
カドリアン09

hehe、私はいつもxargsを忘れています。;)一日の終わりに、何でも仕事を終わらせる。

MacOSXはデフォルトで(つまり、自作の外部で)適切なものをサポートしていないため、xargsこのフォームが必要でした。しかし、彼らにスペースを持つファイルを、あなたはIFSを設定する必要があります:IFS=$'\n'
HankCa

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.