web-dev-qa-db-ja.com

サイズでdu -h出力を並べ替える方法

人間が読める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を並べ替える方法を知っている人はいますか?

1029
Tom Feiner

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)

1444
ptman
du | sort -nr | cut -f2- | xargs du -hs
89
cadrian

@ダグラスリーダー、もう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}'
62
Adam Bellaire

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

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

私が見る限り、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
21
Douglas Leeder

私にもその問題があり、現在回避策を使用しています。

du -scBM | sort -n

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

20
Joachim Sauer

見つかりました この投稿 他の場所。したがって、このシェルスクリプトは、すべてに対して2回duを呼び出さなくても、必要な処理を実行します。 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

(360万色の配色が多すぎないことを願っています。)

19
Adam Bellaire

このバージョンはawkを使用して、ソートキー用の追加の列を作成します。 duを呼び出すのは1回だけです。出力は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に置き換えます。単位がない場合(サイズが1K未満の場合)、一致はなく、ゼロが返されます(完璧! )
  • 新しいフィールド-単位、値(アルファソートを適切に機能させるために、ゼロが埋め込まれた固定長)と元の行を出力します
  • サイズフィールドの最後の文字にインデックスを付ける
  • サイズの数値部分を引き出します
  • 結果を並べ替え、余分な列を破棄する

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]]}'

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

% 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
15
slm

mBのサイズでファイルをソートする

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

私はシンプルですが便利ですpython duのラッパー dutop と呼びます。私たち(coreutilsのメンテナー)は、 "human"をソートする機能を追加することを検討しています。直接出力します。

9
pixelbeat

別のものを得た:

$ 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でも実行できることを知っています。たぶんデュパート。

9
0x89

このスニペットは 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;
     }
    '
8
Bozojoe

「-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
7
Mick T

これはオンラインで見つかりました...正常に動作しているようです

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
5
Peter Nunn

これは私が使用するシンプルな方法で、リソース使用量が非常に少なく、必要なものが得られます。

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
JacobN

私はこの例を昨日作り出すことから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桁で表示されます。

4
marlar

別のもの:

du -h | Perl -e'
@l{ K, M, G } = ( 1 .. 3 );
print sort {
    ($aa) = $a =~ /(\w)\s+/;
    ($bb) = $b =~ /(\w)\s+/;
    $l{$aa} <=> $l{$bb} || $a <=> $b
  } <>'
4

du -cka --max-depth = 1/var/log |並べ替え-rn |頭-10 | awk '{print($ 1)/ 1024、 "MB"、$ 2'}

3
Patrick

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

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

追加のsedステートメントは、アプリケーションサポートなどの名前のフォルダーに関する問題を緩和するのに役立ちます

2
Chealion

ボイラ:

du -sk /var/log/* | sort -rn | awk '{print $2}' | xargs -ia du -hs "a"
1
weeheavy

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

これは、すべてのシステムで機能する d および awk を使用したPOSIX準拠のソリューションです。

私は少し異なるアプローチをとり、-xを追加して同じファイルシステムに留まるようにしました(この操作が必要になるのは、ディスク領域が不足しているときだけなので、この中にマウントしたものを取り除きます) FS treeまたはmove and symlinked back?)と定数単位を表示して、視覚的な解析を容易にします。この場合、私は通常notを選択します階層構造がよく見えるように並べ替えます。

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

(これは一貫した単位であるため、本当に必要な場合は| sort -nを追加できます sort edの結果。)

これにより、(累積)コンテンツが512MBを超えることができないディレクトリがすべて除外され、サイズがギガバイト単位で表示されます。デフォルトでは、duは512バイトのブロックサイズを使用します(awkの条件は2です)20 ブロックは512MBで、その221 除数は単位をGBに変換します— du -kx$1 > 512*1024およびs/1024^2とともに使用して、人間が読みやすくすることができます)。 awk条件の中で、sをサイズに設定して、行($0)から削除できるようにします。これは区切り文字(単一のスペースに折りたたまれている)を保持するため、最後の%sはスペースを表し、次に集約されたディレクトリの名前を表します。 %7sは、丸めた%.2f GBサイズに合わせます(> 10TBの場合は%8sに増やします)。

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

1
Adam Katz

別の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
user96753

http://dev.yorhel.nl/ncd

コマンド:ncdu

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

1
Adam Eickhoff

私は@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);
}'
1
Keith Yoder

du -s * |ソート-nr |カット-f2 | xargs du -sh

1
ageek2remember

ここに例があります

du -h /folder/subfolder --max-depth=1 | sort -hr

戻り値:

233M    /folder/subfolder
190M    /folder/subfolder/myfolder1
15M     /folder/subfolder/myfolder4
6.4M    /folder/subfolder/myfolder5
4.2M    /folder/subfolder/myfolder3
3.8M    /folder/subfolder/myfolder2

また、| head -10を追加して、指定したディレクトリの上位10個または任意の数のサブフォルダを検索することもできます。

1
ode2k

これは私の.profileにあるエイリアスです

エイリアスdu = 'Sudo du -xh --max-depth = 1 |ソート-h '

sort -hは、尋ねられた質問に対してここで本当に役立つものです。

もう1つの便利なオプションは、同じファイルシステムに留まるdu -xです。また、Sudoは、誰もが読めないディレクトリがある場合にエラーが表示されないようにします。また、私は常にdu --max-depth = 1を実行してから、さらにドリルダウンします。

0
Tagar

さらに別のduスクリプト!

すでにたくさんの答えがあるので、私は自分のスクリプトをそこに投稿するだけです。今から8年以上使っています。

これは、

/somepath/rdu.sh [-b] [/somepath] [minSize]

どこ

  • オプションのフラグ-bは、block countの代わりにbyte countを使用するように指示します
  • オプションのpathを最初の引数として、デフォルトの場合は現在のディレクトリ。
  • 2番目の引数を指定しない場合、出力される最小サイズは256Mbです。

出力は次のようになります。

\___   3.01G                 21.67%                .cache
|   \___   1.37G                 45.54%                mozilla
|   |   \___   1.37G                100.00%                firefox
|   |   |   \___ 581.71M                 41.48%                billiethek.default
|   |   |   |   \___ 522.64M                 89.85%                cache2
|   |   |   |   |   \___ 522.45M                 99.96%                entries
...

スクリプトがあります:

#!/bin/bash

if [ "$1" == "-b" ] ;then
    shift
    units=(b K M G T P)
    duargs="-xbs"
    minsize=${2:-$((256*1024**2))}
else
    units=(K M G T P)
    duargs="-xks"
    minsize=${2:-$((256*1024))}
fi

humansize() {
    local _c=$1 _i=0
    while [ ${#_c} -gt 3 ] ;do
        ((_i++))
        _c=$((_c>>10))
    done
    _c=$(( ( $1*1000 ) >> ( 10*_i ) ))
    printf ${2+-v} $2 "%.2f%s" ${_c:0:${#_c}-3}.${_c:${#_c}-3} ${units[_i]}
}
percent() {
    local p=000$((${1}00000/$2))
    printf ${3+-v} $3 "%.2f%%" ${p:0:${#p}-3}.${p:${#p}-3}
}

device=$(stat -c %d "${1:-.}")
printf -v sep "%16s" ""

rdu() {
    local _dir="$1" _spc="$2" _crt _siz _str _tot _pct
    while read _siz _crt;do
        if [ "$_crt" = "total"  ]; then
            _tot=$_siz
        else
            [ "$_tot" ] || _tot=$_siz
            if [ $_siz -gt $minsize ];then
                humansize $_siz _str
                percent $_siz $_tot _pct
                printf "%s\___ %7s%s%7s%s%s\n" \
                    "$_spc" $_str "$sep" $_pct "$sep" "${_crt##*/}"
                [ -d "$_crt" ] &&
                [ $(stat -c %d "$_crt") -eq $device ] &&
                rdu "$_crt" "|   $_spc"
            fi
        fi
    done < <(
        find "$_dir" -mindepth 1 -maxdepth 1 -xdev \
            \( -type f -o -type d \) -printf "%D;%p\n" |
            sed -ne "s/^${device};//p" |
            tr \\n \\0 |
            xargs -0 du ${duargs}c |
            sort -nr
    )
}

rdu "${1:-.}"

いいえ、Git***.xxxには投稿しません。

そこに表示 または そこにスクリプトをダウンロード

0
F. Hauri

私の解決策は、duを1回だけ呼び出す単純なbashスクリプトで、サイズが1 MB以上のディレクトリのみを表示します。

#!/bin/env bash
# Usage: my_du.sh [subdirectory levels]
#   For efficiency, only calls "du" once, and stores results in a temp file
#   Stephen Becker, 2/23/2010

if [ $# -gt 0 ]; then
# You may prefer, as I do, to just summarize the contents of a directory
# and not view the size of its subdirectories, so use this:
    du -h --max-depth $1 > temp_du_file
else
    du -h > temp_du_file
fi


# Show all directories of size > 1 GB:
cat temp_du_file | grep "^\([0-9]\|\.\)\+G" | sort -nr
# Show all directories of size > 1 MB:
cat temp_du_file | grep "^\([0-9]\|\.\)\+M" | sort -nr

rm temp_du_file
0
Stephen

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

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

0
schnaader

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

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

お役に立てば幸いです。

0
Christian Witts
du | sort -nr | awk '{ cmd = "du -h -d0 "$2"| cut -f1"; cmd | getline human; close(cmd); print human"\t"$2 }'
0
Nathan de Vries

次の解決策はcadrianのオリジナルと似ていますが、ツリー内の各ディレクトリに対して1つのduを実行するのではなく、2つのduコマンドのみを実行します。

du -hs `du |sort -g |cut -f2- `

ただし、Cardrianのソリューションは、duに渡される引数のサイズの制限を超える可能性があるため、人口が非常に多いツリーでは機能しないため、より堅牢です。

0
Steve Weet

大まかに this one-liner のロジックに基づいて、人間が読み取れるソートされたdu(1)出力を提供するスクリプトを作成しました。 -h人間が読みやすいようにフラグを立てます。POSIXと互換性のない他のコマンドは必要ありません。

https://github.com/pleappleappleap/sorted-human-d で入手できます。

0
Tripp Kinetics

リングに別の帽子を投げてみませんか....それは古い質問ですが、これは(ほとんど)純粋なシェルスクリプト(fwiw)の例です-つまり、bashだけでPerl/python/awk/etcはありません。その意味で、おそらくそれはディスカッションに新しい何かを提供します(またはしません)。ファイルサイズは1回だけ計算されますが、さまざまな単位で印刷されます(私の好み)。 (簡略化されていないバージョンには、不要な場合に「GB」を除外するgetoptsが含まれています。)

#!/bin/bash

printf -- ' %9s %9s %9s       %-30s\n' 'K'        'M'        'G'        'Path'
printf -- ' %9s %9s %9s       %-30s\n' '--------' '--------' '--------' '-----------'
du -sk "$@" | while read val; do
    file=$(echo "$val" | cut -f2-)
    size_k=$(echo "$val"  | cut -f1)
    printf ' %9s %9s %9s       %-30s\n' \
          ${size_k}  \
          $(( size_k / 1024 ))  \
          $(( size_k / 1024 / 1024 ))  \
          "$file"
  done | sort -n
0
michael

降順で並べ替えます。

du -s ./* | sort -n| cut -f 2-| xargs du -sh {}
0
Peter Nduati