it-swarm-tr.com

Du -h çıktısını boyuta göre nasıl sıralayabilirim?

İnsan tarafından okunabilir du çıktısının bir listesini almam gerekiyor.

Ancak, du "boyuta göre sırala" seçeneğine sahip değildir ve sort ile yapılan borular insan tarafından okunabilir bayrakla çalışmaz.

Örneğin;

du | sort -n -r 

Boyuta göre sıralanmış disk kullanımı çıktısı (azalan):

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

Ancak, insan tarafından okunabilir bayrağıyla çalıştırmak düzgün sıralanmaz:

du -h | sort -n -r

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

Herkes sıralamak için bir yol biliyor mu du -h boyuta göre?

1029
Tom Feiner

GNU coreutils 7.5 Ağustos 2009'da yayımlanan sort, -h Tarafından üretilen türde sayısal soneklere izin veren bir du -h Parametresine izin verir:

du -hs * | sort -h

-h 'U desteklemeyen bir sıralama kullanıyorsanız, eski bir Mac OS X'e GNU Coreutils. Ör.

brew install coreutils
du -hs * | gsort -h

sortmanuel :

-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, bir cevap daha: du-h'den okunabilir çıktıyı başka bir araç kullanarak sıralayın. Perl gibi!

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)}<>;'

Ekrana sığması için iki satıra bölün. Bu şekilde kullanabilir veya tek astar yapabilirsiniz, her iki şekilde de çalışır.

Çıktı:

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

DÜZENLEME: PerlMonks adresinde golf birkaç tur sonra, nihai sonuç şudur:

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

Bu sinir bozucu yüksek disk kullanım klasörlerini ve dosyalarını bulmak ve kaldırmak için tasarlanmış ncd adlı son derece kullanışlı bir araç var. Konsol tabanlı, hızlı ve hafif ve tüm büyük dağıtımlarda paketler var.

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

Görebildiğim kadarıyla üç seçeneğiniz var:

  1. Görüntülenmeden önce sıralamak için du değerini değiştirin.
  2. Sayısal sıralama için insan boyutlarını desteklemek üzere sort değerini değiştirin.
  3. Temel çıktıyı insan tarafından okunabilir hale getirmek için çıktıyı sıralamadan işleme koyun.

Ayrıca du -k ve KiB boyutlarında yaşıyor.

3. seçenek için aşağıdaki komut dosyasını kullanabilirsiniz:

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

Ben de bu sorunu yaşadım ve şu anda bir geçici çözüm kullanıyorum:

du -scBM | sort -n

Bu ölçeklendirilmiş değerler üretmez, ancak her zaman boyutu megabayt cinsinden üretir. Bu mükemmelden daha az, ama benim için hiçbir şeyden daha iyi (veya boyutu bayt cinsinden görüntülemek).

20
Joachim Sauer

bu yayın başka bir yerde bulundu. Bu nedenle, bu Shell betiği her şeyi iki kez du çağırmadan istediğinizi yapar. Ham baytları insan tarafından okunabilir bir biçime dönüştürmek için awk kullanır. Elbette, biçimlendirme biraz farklıdır (her şey bir ondalık basamak hassasiyetine yazdırılır).

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

Bunu .vim dizin verimi:

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

(Umarım 3.6M renk şemaları aşırı değildir.)

19
Adam Bellaire

Bu sürüm, sıralama anahtarları için ek sütunlar oluşturmak üzere awk kullanır. Yalnızca bir kez du çağırır. Çıktı tam olarak du şeklinde görünmelidir.

Birden fazla hatta ayırdım, ancak tek astarlı olarak yeniden birleştirilebilir.

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

Açıklama:

  • BEGIN - üniteler halinde gruplandırma için K, M, G yerine 1, 2, 3 yerine dizine eklenecek bir dize oluşturun, birim yoksa (boyut 1K'dan küçükse), eşleşme yoktur ve sıfır döndürülür (mükemmel! )
  • yeni alanları (birim, değer (alfa sıralamasının düzgün çalışması için sıfır dolgulu, sabit uzunlukta) ve orijinal satırını yazdırın
  • boyut alanının son karakterini indeksle
  • boyutun sayısal kısmını dışarı çekin
  • sonuçları sıralayın, fazladan sütunları atın

Ne yaptığını görmek için cut komutu olmadan deneyin.

AWK betiğindeki sıralamayı yapan ve cut gerektirmeyen bir sürüm:

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

Dizinleri daha kompakt bir özet halinde gösteren bir örnek. Dizin/dosya adlarındaki boşlukları işler.

% 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

dosyaları MB olarak boyuta göre sırala

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

Basit ama kullanışlı python sarıcı dutop olarak adlandırılır. doğrudan çıktı.

9
pixelbeat

Başka bir tane var:

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

Perl'i sevmeye başlıyorum. Yapmanız gerekebilir

$ cpan Number::Bytes::Human

ilk. Oradaki tüm Perl bilgisayar korsanlarına: Evet, sıralama bölümünün Perl'de de yapılabileceğini biliyorum. Muhtemelen du kısmı da.

9
0x89

Bu pasaj utanmaz bir şekilde 'Jean-Pierre' den http://www.unix.com/Shell-programming-scripting/32555-du-h-sort.html adresinden takıldı. Ona daha iyi kredi vermemin bir yolu var mı?

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" bayrağını kullanın

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

Ve/usr/local dizinimde şöyle çıktı üretilir:

$ 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

Bu on line bulundu ... çalışıyor gibi görünüyor

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

Kullandığım basit yöntem, çok düşük kaynak kullanımı ve ihtiyacınız olanı size getiriyor:

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'yi bu örneği uydurmaktan öğrendim. Biraz zaman aldı, ama çok eğlenceliydi ve awk kullanmayı öğrendim.

Sadece du bir kez çalışır ve du -h'ye çok benzer bir çıktıya sahiptir.

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

Bir ondalık basamak ile 10'un altındaki sayıları gösterir.

4
marlar

Bir diğeri:

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 --maks-derinliği = 1/var/log | sıralama -rn | kafa -10 | awk '{baskı (1 $)/1024, "MB", 2 $'}

3
Patrick

Boşlukları işlemeniz gerekiyorsa aşağıdakileri kullanabilirsiniz

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

Ek sed ifadesi, Uygulama Desteği gibi adlara sahip klasörlerle ilgili sorunların hafifletilmesine yardımcı olacaktır

2
Chealion

Voilà:

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

Burada birçoğu yinelenen birçok cevap var. Üç eğilim görüyorum: ikinci bir du çağrısı ile borulama, karmaşık Shell/awk kodu kullanma ve diğer dilleri kullanma.

Her sistemde çalışması gereken d ve awk kullanan POSIX uyumlu bir çözüm .

-x Aynı dosya sisteminde kaldığımızdan emin olmak için (bu işleme yalnızca disk alanım yetersiz olduğunda ihtiyacım var, bu yüzden neden bu içeriğe monte ettiğim şeyleri ayıkladım FS ağaç veya taşındı ve symlinked geri?) ve daha kolay görsel ayrıştırma yapmak için sabit birimleri görüntüleme.Bu durumda, sıralamak için genellikle değil seçerek hiyerarşik yapıyı daha iyi görebiliyorum.

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

(Bu tutarlı birimlerde olduğu için, | sort -n gerçekten istiyorsanız sıralama ed sonuçları.)

Bu, (birikimli) içeriği 512 MB'ı geçmeyen tüm dizinleri filtreler ve ardından boyutları gigabayt cinsinden görüntüler. Varsayılan olarak, du 512 baytlık bir blok boyutu kullanır (yani awk durumu 220 bloklar 512MB ve 221 bölen birimleri GB'ye dönüştürür - du -kx ile $1 > 512*1024 ve s/1024^2 daha okunabilir olması). Awk koşulunda, s değerini boyuta ayarladık, böylece satırdan kaldırabiliriz ($0). Bu, sınırlayıcıyı (tek bir boşluğa daraltılmış) korur, böylece son %s bir alanı ve ardından toplanan dizinin adını temsil eder. %7s yuvarlatılmış %.2f GB boyut (%8s> 10 TB varsa).

Buradaki çözümlerin çoğundan farklı olarak, bu, adlarında boşluk bulunan dizinleri düzgün bir şekilde destekler (buna rağmen her çözüm, bir, satır sonları içeren dizin adlarını yanlış kullanır).

1
Adam Katz

Başka bir awk çözümü -

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

komut: ncdu

Rehberde gezinme, sıralama (ad ve boyut), grafik, okunabilir vb.

1
Adam Eickhoff

@Ptman tarafından sağlanan çözümü kullanıyordum, ancak son zamanlarda yapılan bir sunucu değişikliği artık geçerli değildi. Bunun yerine, aşağıdaki bash betiğini kullanıyorum:

#!/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 * | sıralama -nr | kesim -f2 | xargs du -sh

1
ageek2remember

İşte bir örnek

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

İadeler:

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

Ayrıca | head -10 belirtilen dizindeki ilk 10 veya herhangi bir sayıda alt klasörü bulmak için.

1
ode2k

Bu, .profile'mda bulunan takma ad

takma ad du = 'Sudo du -xh --maks-derinliği = 1 | sıralama -h '

sort -h burada sorulan soruya gerçekten yardımcı olan şeydir.

Diğer bir yararlı seçenek de dux dosyalarının aynı dosya sisteminde kalması; ayrıca Sudo dünya tarafından okunamayan dizinler varsa hataları görmemeye yardımcı olur. Ayrıca, her zaman du - max-derinlik = 1 yapıyorum, sonra daha fazla ayrıntıya iniyorum vs.

0
Tagar

Yine başka bir du betiği!

Zaten çok fazla cevap olduğu için, kendi senaryomu orada yayınlıyorum Sekiz yıldan fazla bir süredir kullanıyorum.

Bu tarafından çalıştırılabilir

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

nerede

  • isteğe bağlı bayrak -bblok sayısı yerine bayt sayısı
  • isteğe bağlı yol 1. bağımsız değişken olarak, varsayılansa geçerli dizin.
  • ikinci bir argüman verilmezse, yazdırılacak minimum boyut 256Mb.

Çıktı şöyle görünebilir:

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

Senaryo var:

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

Ve hayır, onları yayınlamayacağım Git***.xxx.

onları orada göster veya oradaki betiği indirebilirsiniz.

0
F. Hauri

İşte benim çözüm, sadece bir kez du çağıran ve size sadece 1 MB veya daha büyük dizinleri gösteren basit bir bash betiği:

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

En azından olağan araçlarla, bu, insan tarafından okunabilir sayıların bulunduğu format nedeniyle zor olacaktır (508, 64, 61, 2, 2 - sayıları sıraladığı için burada sıralama "iyi bir iş" yapar) ek bir çarpanla kayan nokta sayılarını sıralayamaz).

Ben başka bir şekilde denemek istiyorum - "du | sort -n -r" çıkış kullanın ve daha sonra bazı komut dosyası veya program ile sayıları insan tarafından okunabilir formata dönüştürmek.

0
schnaader

Deneyebileceğiniz şey:

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

Umarım yardımcı olur.

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

Aşağıdaki çözüm cadrian'ın orijinaline benzer, ancak bu ağaçtaki her dizin için bir du yerine sadece 2 du komutu çalıştırır.

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

Bununla birlikte, Cardrian'ın çözümü daha sağlamdır, çünkü yukarıdakiler çok yoğun nüfuslu ağaçlar için işe yaramayacaktır, çünkü du'ya aktarılan argümanların boyut sınırını aşabilir

0
Steve Weet

Gevşek mantık dayalı bu one-liner , ben bir insan okunabilir du (1) sıralı çıkış sağlayan bir komut dosyası yazdı. İnsan tarafından okunabilirlik için -h Bayrağını zorunlu kılmak dışında, POSIX uyumlu olmayan başka komutlar gerektirmez.

https://github.com/pleappleappleap/sorted-human-d adresinde bulunabilir.

0
Tripp Kinetics

Neden halka başka bir şapka atmıyorum .... eski bir soru, ama işte (çoğunlukla) saf Shell betiği (fwiw) - yani, sadece bash ve Perl/python/awk/vb. Bu anlamda belki de tartışma için yeni bir şey sunuyor (ya da değil). Dosya boyutunu yalnızca bir kez hesaplar, ancak çeşitli birimlerde yazdırır (benim tercihim). (Basitleştirilmiş sürüm, istenmeyen "GB" ı hariç tutan getopts içerir.)

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

Azalan düzende sıralar.

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