Bagaimana Anda mengurutkan du output berdasarkan ukuran?

196

Bagaimana Anda mengurutkan du -sh /dir/*berdasarkan ukuran? Saya membaca satu situs yang mengatakan menggunakan | sort -ntetapi itu jelas tidak benar. Berikut ini contoh yang salah.

[~]# du -sh /var/* | sort -n
0       /var/mail
1.2M    /var/www
1.8M    /var/tmp
1.9G    /var/named
2.9M    /var/run
4.1G    /var/log
8.0K    /var/account
8.0K    /var/crash
8.0K    /var/cvs
8.0K    /var/games
8.0K    /var/local
8.0K    /var/nis
8.0K    /var/opt
8.0K    /var/preserve
8.0K    /var/racoon
12K     /var/aquota.user
12K     /var/portsentry
16K     /var/ftp
16K     /var/quota.user
20K     /var/yp
24K     /var/db
28K     /var/empty
32K     /var/lock
84K     /var/profiles
224M    /var/netenberg
235M    /var/cpanel
245M    /var/cache
620M    /var/lib
748K    /var/spool
xenoterracide
sumber
3
Saya tahu saya pernah melihat ini sebelumnya . The jawaban tertinggi sebagai ada sangat tidak baik, tetapi orang lain yang lebih baik .
Gilles
Jawaban yang diterima sort -hbekerja untuk saya di Ubuntu 16,04 LTS pada Agustus 2017. Pertama saya menemukan drive yang saya pasang oleh cd /mnt(dipasang oleh UUID di fstab). Lalu saya lakukan du >~/dumnt.out maka sort -h ~/dumnt.out >~/dumntsort.outsaya bisa melakukan `tail ~ / dumntsort.out untuk melihat ruang babi terbesar.
SDsolar

Jawaban:

252

Jika Anda memiliki GNU coreutils (umum di sebagian besar distribusi Linux), Anda dapat menggunakannya

du -sh -- * | sort -h

The -hpilihan menceritakan sortbahwa input adalah format yang dapat dibaca manusia (nomor dengan satuan; 1024 berbasis sehingga 1023 dianggap kurang dari 1K yang terjadi sesuai dengan apa GNU du -htidak).

Fitur ini ditambahkan ke GNU Core Utilities 7.5 pada Agustus 2009 .

catatan:

Jika Anda menggunakan versi Mac OSX yang lebih lama, Anda harus menginstal coreutils dengan brew install coreutils, lalu gunakan gsortsebagai pengganti drop-in sort.

Versi MacOS yang lebih baru (diverifikasi di Mojave) mendukung sort -hsecara asli.

Shawn J. Goff
sumber
27
catatan: tambahkan -runtuk mengurutkan, jika Anda ingin yang besar di atas
xenoterracide
9
Pada OSX Anda dapat menginstal coreutilsmelalui brewdan menambahkan folder bin PATHke file rc Anda , dan -hharus tersedia.
kenorb
Oh - terima kasih atas pengingatnya. itu berarti saya tidak perlu tailperintah untuk melihat babi.
SDsolar
47

Coba gunakan flag -k untuk menghitung 1K blok sebelum menggunakan yang dapat dibaca manusia. Kemudian, Anda memiliki unit umum dan dapat dengan mudah melakukan pengurutan angka.

du -ck | sort -n

Anda tidak secara eksplisit membutuhkan unit manusia, tetapi jika Anda melakukannya, maka ada banyak cara untuk melakukannya. Banyak yang tampaknya menggunakan teknik blok 1K di atas, dan kemudian melakukan panggilan kedua ke du.

https://serverfault.com/questions/62411/how-can-i-sort-du-h-output-by-size

Jika Anda ingin melihat unit KB ditambahkan, gunakan:

du -k | sed -e 's_^\([0-9]*\)_\1 KB_' | sort -n
pboin
sumber
2
senang tidak harus menginstal sesuatu yang lain untuk mendapatkan hasil yang saya butuhkan
taranaki
16

Jika Anda tidak memiliki versi terbaru GNU coreutils , Anda dapat menelepon dutanpa -hmendapatkan output yang dapat diurutkan, dan menghasilkan output yang ramah manusia dengan sedikit postprocessing. Ini memiliki keuntungan bekerja bahkan jika versi duAnda tidak memiliki -hbenderanya.

du -k | sort -n | awk '
    function human(x) {
        if (x<1000) {return x} else {x/=1024}
        s="kMGTEPZY";
        while (x>=1000 && length(s)>1)
            {x/=1024; s=substr(s,2)}
        return int(x+0.5) substr(s,1,1)
    }
    {gsub(/^[0-9]+/, human($1)); print}'

Jika Anda ingin sufiks SI (mis. Kelipatan 1000 daripada 1024), ubah 1024 hingga 1000 di whilebadan loop. (Perhatikan bahwa 1000 dalam kondisi tersebut dimaksudkan, sehingga Anda mendapatkan mis. 1MDaripada 1000k.)

Jika Anda dumemiliki opsi untuk menampilkan ukuran dalam byte (misalnya -batau -B 1- perhatikan bahwa ini mungkin memiliki efek samping menghitung ukuran file yang sebenarnya daripada penggunaan disk), tambahkan spasi ke awal s(yaitu s=" kMGTEPYZ";), atau tambahkan if (x<1000) {return x} else {x/=1024}di awal yang humanfungsi.

Menampilkan angka desimal untuk angka dalam kisaran 1–10 dibiarkan sebagai latihan bagi pembaca.

Gilles
sumber
Ini adalah solusi satu-satunya yang saya temukan bekerja pada linux dan mac. Terima kasih banyak!
Brian Graham
9

Jika tidak punya, sort -hAnda bisa melakukan ini:

du -sh * | sed 's/\([[:digit:]]\)\t/\1B\t/' | sed 's/\(.\t\)/\t\1/' | sed 's/G\t/Z\t/' | sort -n -k 2d,2 -k 1n,1 | sed 's/Z\t/G\t/'

Ini mendapatkan daftar du, memisahkan akhiran, dan mengurutkan menggunakan itu. Karena tidak ada akhiran untuk <1K, sed pertama menambahkan B (untuk byte). Sed kedua menambahkan pembatas antara digit dan akhiran. Sed ketiga mengkonversi G ke Z sehingga lebih besar dari M; jika Anda memiliki file terabyte, Anda harus mengonversi G ke Y dan T ke Z. Akhirnya, kami mengurutkan berdasarkan dua kolom, lalu kami mengganti akhiran G.

Shawn J. Goff
sumber
Upaya luar biasa, tetapi ini tidak mendekati bekerja untuk saya.
jvriesem
6

Pada OS X, Anda dapat menginstal coreutils yang dibutuhkan melalui Homebrew :

brew install coreutils

Dengan ini Anda akan miliki gsort, yang meliputi -hparameter baris perintah.

Roland
sumber
4

Script Perl kecil ini berhasil. Simpan sebagai duh(atau apa pun yang Anda inginkan) dan sebut denganduh /dir/*

#!/usr/bin/perl -w
use strict;

my @line;

sub to_human_readable {
        my ($number) = @_;
        my @postfix = qw( k M G T P );
        my $post;
        my $divide = 1;
        foreach (@postfix) {
                $post = $_;
                last if (($number / ($divide * 1024)) < 1);
                $divide = $divide * 1024;
        }
        $number = int($number/$divide + 0.5);
        return $number . $post;
}

sub trimlengthright {
        my ($txt, $len) = @_;
        if ( length($txt) >= $len ) {
                $txt = substr($txt,0,$len - 1) . " ";
        } else {
                $txt = $txt . " " x ($len - length($txt));
        }
        return $txt;
}

sub trimlengthleft {
        my ($txt, $len) = @_;
        if ( length($txt) >= $len ) {
                $txt = substr($txt,0,$len - 1) . " ";
        } else {
                $txt = " " x ($len - length($txt)) . $txt;
        }
        return $txt;
}

open(DF,"du -ks @ARGV | sort -n |");
while (<DF>) {
        @line = split;
        print &trimlengthleft(&to_human_readable($line[0]),5)," "; # size
        print &trimlengthright($line[1],70),"\n"; # directory
}
close DF;
ddeimeke
sumber
4

Karena Mac OS X tidak memiliki -hopsi untuk sort, maka saya mencoba dan belajar seddan awkuntuk upaya pertama:

du -sk * | sort -g | awk '{ numBytes = $1 * 1024; numUnits = split("B K M G T P", unit); num = numBytes; iUnit = 0; while(num >= 1024 && iUnit + 1 < numUnits) { num = num / 1024; iUnit++; } $1 = sprintf( ((num == 0) ? "%6d%s " : "%6.1f%s "), num, unit[iUnit + 1]); print $0; }'

itu adalah garis panjang. Diperluas, yaitu:

du -sk * | sort -g | awk '{ 

    numBytes = $1 * 1024; 
    numUnits = split("B K M G T P", unit); 
    num = numBytes; 
    iUnit = 0; 

    while(num >= 1024 && iUnit + 1 < numUnits) { 
        num = num / 1024; 
        iUnit++; 
    } 

    $1 = sprintf( ((num == 0) ? "%6d%s " : "%6.1f%s "), num, unit[iUnit + 1]);
    print $0; 

}'

Saya mencobanya di Mac OS X Mavericks, Yosemite, Ubuntu 2014-04 dengan awkmenjadi default awk(yaitu nawk, karena keduanya awkdan nawkmenunjuk ke /usr/bin/mawk) atau melongo, dan mereka semua bekerja.

Berikut adalah contoh output pada Mac:

     0B  bar
     0B  foo
   4.0K  wah
  43.0M  Documents
   1.2G  Music
   2.5G  Desktop
   4.7G  Movies
   5.6G  VirtualBox VMs
   9.0G  Dropbox
  11.7G  Library
  21.2G  Pictures
  27.0G  Downloads

alih-alih du -sk *, saya melihat jawaban @ Stefan di mana grand total juga ditampilkan, dan tanpa melintasi titik mount sistem file apa pun, dengan menggunakandu -skcx *

nopole
sumber
1

Inilah yang saya gunakan di Ubuntu 10.04, CentOS 5.5, FreeBSD dan Mac OS X.

Saya meminjam ide dari www.geekology.co.za/ dan earthinfo.org , serta bebek terkenal dari "Linux Server Hacks" oleh O'Reilly. Saya masih menyesuaikannya dengan kebutuhan saya. Ini masih dalam proses (Seperti, saya sedang mengerjakan ini di kereta pagi ini.):

#! /usr/bin/env bash
ducks () {
    du -cks -x | sort -n | while read size fname; do
        for unit in k M G T P E Z Y; do
            if [ $size -lt 1024 ]; then
                echo -e "${size}${unit}\t${fname}"
                break
            fi
            size=$((size/1024))
        done
    done
}
ducks > .ducks && tail .ducks

Inilah hasilnya:

stefan@darwin:~ $ ducks
32M src
42M .cpan
43M .macports
754M    doc
865M    Work
1G  .Trash
4G  Library
17G Downloads
30G Documents
56G total

stefan@darwin:~ $
Stefan Lasiewski
sumber
Saya pikir Anda maksud du -cks -x *? (dengan tanda bintang)
nopole
Tanda bintang berlebihan dalam penggunaan ini. Cobalah.
Stefan Lasiewski
maksud Anda menempatkan set kode pertama ke dalam file bernama ducks, dan kemudian chmod a+x duckskemudian gunakan ./ducksuntuk menjalankannya? Kemudian saya hanya melihat total penggunaan disk, baik di Mac OS X dan di Ubuntu 2014-10. Saya juga mencoba memasukkan ducks() { ...}definisi ke dalam .bashrcdan kemudian menggunakannya ducksuntuk menjalankannya, dan hal yang sama pada Mac OS X, hanya melihat grand total
nopole
1

Gila dengan skrip ini -

$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 singh
sumber
1

Dengan tidak adanya GNU sort -h, ini harus bekerja di sebagian besar lingkungan UNIX:

join -1 2 -2 2 <(du -sk /dir/* 2>/dev/null | sort -k2,2) <(du -sh /dir/* 2>/dev/null | sort -k2,2) | sort -nk2,2 | awk '{ print $3 "\t" $1 }'
friedl.otto
sumber
0

Yang ini menangani nama file dengan spasi putih atau apostrof, dan bekerja pada sistem yang tidak mendukung xargs -datau sort -h:

du -s * | sort -n | cut -f2 | tr '\n' '\0' | xargs -0 -I {} du -sh "{}"

yang mengakibatkan:

368K    diskmanagementd
392K    racoon
468K    coreaudiod
472K    securityd
660K    sshd
3.6M    php-fpm
Mark Crossfield
sumber
0

Ini akan mengurutkan output dengan mengurangi urutan ukuran:

du -sh /var/* | sort -k 1rn

Ini akan mengurutkan output dalam urutan ukuran yang meningkat:

du -sh /var/* | sort -k 1n

PS: ini dapat digunakan untuk mengurutkan berdasarkan kolom mana pun tetapi nilai kolom itu harus dalam format yang sama

pengguna5337995
sumber
1
Tidak sort -k1rnsama dengan sort -rndan hanya mengurutkan secara numerik berdasarkan urutan awal angka desimal pada setiap baris. Ini tidak memahami floating point, dan tidak memahami k, M, G... akhiran. 10.1k akan dianggap lebih besar dari 1.23G
Stéphane Chazelas
0

Diuji pada Solaris!

du -kh | sort -nk1 | grep [0-9]K && du -kh | sort -nk1 | grep [0-9]M && du -kh | sort -nk1 | grep [0-9]G

Ini akan menampilkan semua ukuran direktori secara rekursif, di bagian bawah akan menjadi direktori terbesar dalam Gigabytes dan di bagian atas terkecil di Kilobyte.

Chuguniy
sumber
0

Yang terbesar ada di bawah:

du -sh * | sort -h
Meskan
sumber
0

Perintah:

du -ah . | sort -k1 -h | tail -n 50

Penjelasan:

  • Daftar ukuran semua file / folder secara rekursif dalam direktori saat ini dalam bentuk yang dapat dibaca manusia

du -ah .

  • Urutkan ukuran yang bisa dibaca manusia yang ada di kolom pertama dan pertahankan yang terbesar 50

sort -k1 -h | tail -n 50

Rohan Ghige
sumber
-1

Untuk mengurutkan berdasarkan ukuran dalam MB

du --block-size=MiB --max-depth=1 path | sort -n
lukmansh
sumber
Pengguna ingin mendapatkan hasil du -h(keluaran yang dapat dibaca manusia) diurutkan secara numerik. Anda tidak memberikan jawaban untuk itu. Anda mungkin juga ingin menautkan akun UNIX-SE Anda dengan akun lain yang Anda miliki di situs SE lainnya.
Tonin
-2

Skrip ini bahkan lebih mudah:

for i in G M K; do du -h -d1 / | grep [0-9]$i | sort -n; done
Hobit
sumber
-2

untuk OSX

du -h -k  {PATH} | sort -n
Steve Greensides
sumber
bukan -khanya pembatalan -hdan jika demikian bagaimana hal ini memberikan output yang dapat dibaca manusia yang diminta oleh OP.
Anthon