pengembangan-web-mp-pd.com

Bagaimana saya bisa mengurutkan output du -h berdasarkan ukuran

Saya perlu mendapatkan daftar du keluaran yang dapat dibaca manusia.

Namun, du tidak memiliki opsi "urutkan berdasarkan ukuran", dan perpipaan ke sort tidak berfungsi dengan bendera yang dapat dibaca manusia.

Misalnya, menjalankan:

du | sort -n -r 

Output penggunaan disk yang diurutkan berdasarkan ukuran (turun):

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

Namun, menjalankannya dengan bendera yang dapat dibaca manusia, tidak mengurutkan dengan benar:

du -h | sort -n -r

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

Adakah yang tahu cara menyortir du -h berdasarkan ukuran?

1029
Tom Feiner

Pada GNU coreutils 7.5 dirilis pada Agustus 2009, sort memungkinkan parameter -h, Yang memungkinkan sufiks numerik dari jenis yang dihasilkan oleh du -h:

du -hs * | sort -h

Jika Anda menggunakan jenis yang tidak mendukung -h, Anda dapat menginstal GNU Coreutils. E.g. pada Mac OS X yang lebih lama:

brew install coreutils
du -hs * | gsort -h

Dari sortmanual :

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

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

@Douglas Leeder, satu jawaban lagi: Urutkan output yang dapat dibaca manusia dari du -h menggunakan alat lain. Seperti 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)}<>;'

Bagi menjadi dua garis agar sesuai dengan tampilan. Anda dapat menggunakannya dengan cara ini atau menjadikannya one-liner, itu akan berfungsi baik.

Keluaran:

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

EDIT: Setelah beberapa putaran golf berakhir pada PerlMonks , hasil akhirnya adalah sebagai berikut:

Perl -e'%h=map{/.\s/;99**(ord$&&7)-$`,$_}`du -h`;[email protected]{sort%h}'
62
Adam Bellaire

Ada alat yang sangat berguna yang saya gunakan bernama ncd yang dirancang untuk menemukan folder dan file penggunaan disk yang sial, dan menghapusnya. Berbasis konsol, cepat dan ringan, dan memiliki paket di semua distribusi utama.

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

Sejauh yang saya bisa lihat, Anda memiliki tiga opsi:

  1. Ubah du untuk mengurutkan sebelum tampilan.
  2. Ubah sort untuk mendukung ukuran manusia untuk jenis numerik.
  3. Poskan proses output dari sortir untuk mengubah output dasar menjadi dapat dibaca manusia.

Anda juga bisa melakukan du -k dan hidup dengan ukuran dalam KiB.

Untuk opsi 3 Anda dapat menggunakan skrip berikut:

#!/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

Saya juga punya masalah itu dan saat ini saya sedang menggunakan solusi:

du -scBM | sort -n

Ini tidak akan menghasilkan nilai skala, tetapi selalu menghasilkan ukuran dalam megabita. Itu kurang sempurna, tetapi bagi saya itu lebih baik daripada tidak sama sekali (atau menampilkan ukuran dalam byte).

20
Joachim Sauer

Ditemukan kiriman ini di tempat lain. Karenanya, skrip Shell ini akan melakukan apa yang Anda inginkan tanpa memanggil du pada semuanya dua kali. Ia menggunakan awk untuk mengonversi byte mentah ke format yang dapat dibaca manusia. Tentu saja, formatnya sedikit berbeda (semuanya dicetak ke satu tempat desimal presisi).

#/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
}}}'

Menjalankan ini di direktori .vim Saya menghasilkan:

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

(Saya harap skema warna 3,6M tidak berlebihan.)

19
Adam Bellaire

Versi ini menggunakan awk untuk membuat kolom tambahan untuk mengurutkan kunci. Itu hanya memanggil du sekali. Outputnya harus persis seperti du.

Saya telah membaginya menjadi beberapa baris, tetapi dapat dikombinasi ulang menjadi satu garis.

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

Penjelasan:

  • BEGIN - buat string untuk mengindeks untuk menggantikan 1, 2, 3 untuk K, M, G untuk pengelompokan berdasarkan unit, jika tidak ada unit (ukurannya kurang dari 1K), maka tidak ada kecocokan dan nol dikembalikan (sempurna! )
  • cetak bidang baru - unit, nilai (untuk membuat alpha-sort berfungsi dengan baik, tanpa bantalan, panjang tetap) dan garis asli
  • indeks karakter terakhir dari bidang ukuran
  • tarik bagian numerik dari ukuran
  • urutkan hasilnya, buang kolom tambahan

Cobalah tanpa perintah cut untuk melihat apa yang dilakukannya.

Berikut adalah versi yang melakukan penyortiran dalam skrip AWK dan tidak perlu 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]]}'

Berikut adalah contoh yang menunjukkan direktori dalam bentuk ringkas yang diringkas. Ini menangani spasi di direktori/nama file.

% 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

urutkan file berdasarkan ukuran dalam MB

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

Saya sudah sederhana tapi bermanfaat python wrapper untuk du disebut dutop . Perhatikan bahwa kami (pengelola coreutils) sedang mempertimbangkan untuk menambahkan fungsionalitas untuk menyortir mengurutkan "manusia" output secara langsung.

9
pixelbeat

Dapatkan satu lagi:

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

Saya mulai menyukai Perl. Anda mungkin harus melakukan

$ cpan Number::Bytes::Human

pertama. Untuk semua peretas Perl di luar sana: Ya, saya tahu bahwa bagian pengurutan juga dapat dilakukan di Perl. Mungkin bagian du juga.

9
0x89

Cuplikan ini tanpa malu-malu tersangkut dari 'Jean-Pierre' dari http://www.unix.com/Shell-programming-scripting/32555-du-h-sort.html . Apakah ada cara agar saya bisa lebih menghargai dia?

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

Gunakan bendera "-g"

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

Dan pada direktori/usr/local saya menghasilkan output seperti ini:

$ 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

Menemukan ini online ... tampaknya berfungsi OK

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

Berikut adalah metode sederhana yang saya gunakan, penggunaan sumber daya sangat rendah dan memberi Anda apa yang Anda butuhkan:

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

Saya belajar awk dari meramu contoh ini kemarin. Butuh waktu, tapi itu sangat menyenangkan, dan saya belajar cara menggunakan awk.

Ini berjalan hanya du sekali, dan memiliki output yang mirip dengan 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 }'

Ini menunjukkan angka di bawah 10 dengan satu titik desimal.

4
marlar

Yang lainnya:

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
Dimitre Radoulov

du -cka --max-depth = 1/var/log | sort -rn | kepala -10 | awk '{print ($ 1)/1024, "MB", $ 2'}

3
Patrick

Jika Anda perlu menangani spasi, Anda dapat menggunakan yang berikut ini

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

Pernyataan sed tambahan akan membantu meringankan masalah dengan folder dengan nama seperti Dukungan Aplikasi

2
Chealion

Voa:

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

Ada banyak jawaban di sini, banyak di antaranya adalah duplikat. Saya melihat tiga tren: menyalurkan melalui panggilan kedua, menggunakan kode Shell/awk yang rumit, dan menggunakan bahasa lain.

Berikut ini adalah solusi yang sesuai dengan POSIX menggunakan d dan awk yang akan bekerja pada setiap sistem.

Saya telah mengambil pendekatan yang sedikit berbeda, menambahkan -x untuk memastikan kita tetap pada sistem file yang sama (saya hanya perlu operasi ini ketika saya kekurangan ruang disk, jadi mengapa membuang hal-hal yang telah saya pasang dalam pohon FS atau pindah) dan disinkronkan kembali?) dan menampilkan unit konstan untuk membuat parsing visual yang lebih mudah. ​​Dalam hal ini, saya biasanya memilih bukan untuk mengurutkan sehingga saya dapat melihat struktur hierarkis dengan lebih baik.

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

(Karena ini dalam unit yang konsisten, Anda dapat menambahkan | sort -n jika Anda benar-benar ingin rutkan hasil ed.)

Ini menyaring direktori mana pun yang kontennya (kumulatif) gagal melebihi 512MB dan kemudian menampilkan ukuran dalam gigabytes. Secara default, du menggunakan ukuran blok 512-byte (jadi kondisi 2 di awk20 blok adalah 512MB dan 221 pembagi mengubah unit menjadi GB - kita bisa menggunakan du -kx dengan $1 > 512*1024 dan s/1024^2 agar lebih bisa dibaca manusia). Di dalam kondisi awk, kita mengatur s ke ukuran sehingga kita dapat menghapusnya dari baris ($0). Ini mempertahankan pembatas (yang diciutkan menjadi satu spasi), jadi final %s mewakili spasi dan kemudian nama direktori gabungan. %7s meluruskan yang bulat %.2f Ukuran GB (naik menjadi %8s jika Anda memiliki> 10TB).

Tidak seperti kebanyakan solusi di sini, ini dengan benar mendukung direktori dengan spasi di namanya (walaupun setiap solusi, termasuk ini satu, akan salah menangani nama direktori yang berisi jeda baris).

1
Adam Katz

Solusi awk lain -

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

perintah: ncdu

Navigasi direktori, pengurutan (nama dan ukuran), grafik, dapat dibaca manusia, dll ...

1
Adam Eickhoff

Saya telah menggunakan solusi yang disediakan oleh @ptman, tetapi perubahan server baru-baru ini membuatnya tidak lagi layak. Sebagai gantinya, saya menggunakan skrip bash berikut:

#!/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 * | sort -nr | cut -f2 | xargs du -sh

1
ageek2remember

Berikut ini sebuah contoh

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

Pengembalian:

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

Anda juga bisa menambahkan | head -10 untuk menemukan 10 folder teratas atau sejumlah sub-folder dalam direktori yang ditentukan.

1
ode2k

Ini adalah alias yang saya miliki di profil

alias du = 'Sudo du -xh --max-depth = 1 | semacam-h '

sort -h adalah apa yang benar-benar membantu di sini untuk pertanyaan yang diajukan.

Opsi lain yang bermanfaat adalah du -x untuk tetap pada sistem file yang sama; juga Sudo membantu untuk tidak melihat kesalahan jika ada direktori yang tidak dapat dibaca dunia. Juga, saya selalu melakukan du --max-depth = 1, lalu menelusuri lebih lanjut dll.

0
Tagar

Namun skrip du lain!

Karena sudah ada banyak jawaban, saya hanya memposting skrip saya sendiri di sana. Saya menggunakan lebih dari delapan tahun sekarang.

Ini bisa dijalankan oleh

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

dimana

  • bendera opsional -b katakan untuk menggunakan byte count alih-alih blok hitung
  • opsional path sebagai argumen pertama, direktori saat ini jika default.
  • jika tidak ada argumen kedua yang diberikan, ukuran minimal yang akan dicetak adalah 256Mb.

Outputnya bisa seperti:

\___   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
...

Ada skripnya:

#!/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:-.}"

Dan tidak, saya tidak akan mempostingnya di Git***.xxx.

Anda dapat tunjukkan di sana atau nduh skrip di sana.

0
F. Hauri

Inilah solusi saya, skrip bash sederhana yang hanya memanggil du sekali, dan hanya menampilkan direktori ukuran 1 MB atau lebih besar:

#!/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

Setidaknya dengan alat yang biasa, ini akan sulit karena format angka yang dapat dibaca manusia (perhatikan bahwa semacam melakukan "pekerjaan yang baik" di sini karena mengurutkan angka - 508, 64, 61, 2, 2 - itu tidak bisa mengurutkan angka floating point dengan pengganda tambahan).

Saya akan mencobanya sebaliknya - gunakan output dari "du | sort -n -r" dan kemudian mengonversi angka ke format yang dapat dibaca manusia dengan beberapa skrip atau program.

0
schnaader

Yang bisa Anda coba adalah:

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

Semoga itu bisa membantu.

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

Solusi berikut ini mirip dengan aslinya cadrian namun ini hanya akan menjalankan 2 du perintah sebagai lawan dari satu du untuk setiap direktori di pohon.

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

Namun solusi Cardrian lebih kuat karena hal di atas tidak akan bekerja untuk pohon yang sangat padat penduduknya karena dapat melebihi batas ukuran argumen yang diteruskan ke du

0
Steve Weet

Secara longgar didasarkan pada logika di one-liner ini , saya menulis sebuah skrip yang menyediakan hasil keluaran du (1) yang dapat dibaca oleh manusia. Selain membutuhkan -h flag untuk keterbacaan oleh manusia, tidak memerlukan perintah lain yang tidak kompatibel dengan POSIX.

Ini tersedia di https://github.com/pleappleappleap/sorted-human-d .

0
Tripp Kinetics

Mengapa tidak melempar topi lain ke atas ring .... itu adalah pertanyaan lama, tapi inilah contoh yang (kebanyakan) skrip Shell murni (fwiw) - yaitu, hanya bash dan tanpa Perl/python/awk/etc. Jadi dalam pengertian itu mungkin menawarkan sesuatu yang baru untuk diskusi (atau tidak). Ini menghitung ukuran file hanya sekali, tetapi mencetak dalam berbagai unit (preferensi saya). (Versi yang tidak disederhanakan termasuk getop yang tidak termasuk "GB" jika tidak diinginkan.)

#!/bin/bash

printf -- ' %9s %9s %9s       %-30s\n' 'K'        'M'        'G'        'Path'
printf -- ' %9s %9s %9s       %-30s\n' '--------' '--------' '--------' '-----------'
du -sk "[email protected]" | 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

Mengurutkan dalam urutan menurun.

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