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


966

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

Bununla birlikte, du"boyuta göre sırala" seçeneği yoktur ve boru bağlantıları sortinsan tarafından okunabilen bayrakla çalışmaz.

Örneğin, çalışıyor:

du | sort -n -r 

Sıralı bir disk kullanımı boyutuna göre (azalan) çıkarır:

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

Bununla birlikte, onu insan tarafından okunabilir bayrakla çalıştırmak, doğru şekilde sıralamaz:

du -h | sort -n -r

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

Boyuta göre sıralamanın bir yolunu bilen var mı du -h ?


Heh ... Komik olmalısın, çünkü bu beni rahatsız ediyor ... en azından bir senedir. Geçen hafta kodu GNU coreutil'lerine (hangi türün bir parçası) indirdim ve bir baktım, ancak yama yapmak için elimde olandan biraz daha fazla zaman alacağına karar verdim ... Herkes? :)
gevşeyin

İşte çok ilgili bir soru: serverfault.com/q/737537/35034
cregox

bunu gördün mü? unix.stackexchange.com/questions/4681/… Neredeyse bir kopyası ve altın değerinde. Normal yapıyorsunuz, duancak -h sortkomutunu ekleyin . Bunu ekleyebilir, -rhböylece dosyadaki en büyük dosya ilk olacak, aksi halde tailboşluk çubuklarını görmeniz gerekir .
SDsolar

Buna googledken böyle bir sorunun bu kadar popüler olmasını beklemiyordum.
Mateen Ulhaq

Yanıtlar:


1362

İtibariyle GNU coreutils 7.5 Ağustos 2009'da yayımlanan, sortbir verir -htarafından üretilen türden sayısal eklerini tanır parametreyi, du -h:

du -hs * | sort -h

Desteklemeyen bir sıralama kullanıyorsanız -h, GNU Coreutils'i yükleyebilirsiniz. Örneğin daha eski bir Mac OS X'te:

brew install coreutils
du -hs * | gsort -h

Gönderen sort kılavuzda :

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


3
Kılavuzun ilgili bölümü: gnu.org/software/coreutils/manual/...
wodow

29
Homebrew ile OS X üzerine kurulumu kolay - demlemek kurulum coreutils.
Richard Poirier

41
İyi bir! Ben şahsen her zaman du -BM | sort -nrbir geçici çözüm olarak yaptım - yeterince okunabilir bir insan ve daha eski coreutils ile sıkışık olan biri varsa sıralanır.
chutz

30
Homebrew üzerinden OSX kullanıyorsanız, sıralama yapmak yerine şimdi gsort kullanmanız gerekeceğini unutmayın:du -hs * | gsort -h
Brian Cline

2
@PaulDraper, du -BMher şeyi megabayt olarak yazdırır, böylece 168K olan bir dosya aslında 0M olarak görüntülenir. Farkında değilim başka bir sürüm tutarsızlığı olmadığı sürece. Benim dusürümüm sadece tamsayı megabayt değerlerini gösterir.
chutz

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

48
Ve çok miktarda yinelenen sayma yapar.
Douglas Leeder

1
İlk önce normal du yapar - sonra her giriş için sadece okunabilir biçimde yazdırmak için boyutu yeniden hesaplar.
Douglas Leeder

8
@Douglas Leeder: yinelenen sayma konusunda haklısınız, ancak ikinci du'nun soğuk önbellekten başlamadığını düşünün (işletim sistemi sayesinde) verilen komuta
cadrian

4
Chris'in aslında beyaz boşluk içeren yollar ile çalıştığı için üstündür. Senin yoluna oy veriyorum dostum.
rbright

3
Çirkin, ama çapraz platform :).
voretaq7

62

@Douglas Leeder, bir cevap daha: İnsan tarafından okunabilir çıktısını başka bir araç kullanarak du-h'den ayırı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 ya da bir liner yapabilirsiniz, her iki şekilde de çalışacaktır.

Çıktı:

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

EDIT: PerlMonks'ta birkaç tur golf oynadıktan sonra nihai sonuç şöyle:

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

2
Kısa versiyonunuz çıktı stderralması için diedeğiştirebildiği için çıktı veriyor stdoutmu?
Dennis Williamson

2
Değişim diebir etmek printve onu gidecek stdout. Sadece iki karakter daha.
Adam Bellaire

Ubuntu üzerinde çalışıyor!
marinara

etkileyici perl hackistry
nandoP

Sonuç ters sırada :(
RSFalcon7

55

Bu sinir bozucu yüksek disk kullanımlı klasörleri ve dosyaları bulmak ve bunları kaldırmak için tasarlanmış ncdu adlı kullandığım son derece yararlı bir araç var . Konsol tabanlı, hızlı ve hafiftir ve tüm büyük dağıtımlarda paketleri vardır.


Çok güzel ... Sonuçlar standartlara uygun değilse, kazandım ... El kitabını okuyamayacağım kadar tembelim
ojblass

8
gt5 aynı damardadır ; katil özelliği büyüme gösteriyor.
Tobu,

1
Bu gerçekten havalı! Ve dusadece büyük dizinleri tanımlamak istiyorsanız, takılmaktan çok daha hızlı .
BurninLeo

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

İle kullanılamaz du -k --total, sonunda hata veriyordu: cannot access 'total': No such file or directory
laggingreflex

Bunu bir başka cevabı daha seviyorum. Sadece ilk 50 sonucu nasıl gösterebilirsin?
Mau

1
@Mauro - sadece sonucu headekleyerek boruya `| sonunda -50` kafa.
Samuel Lelièvre

21

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

  1. Alter dugösterilmeden önce sıralamak.
  2. Alter sortsayısal sıralama için insan boyutları desteklemek için.
  3. Temel çıktıyı insan tarafından okunabilir olarak değiştirmek için çıktıyı sıralamadan işlem sonrası.

Ayrıca du -kKiB içinde boyutları ile yapmak ve yaşayabilir.

Seçenek 3 için aşağıdaki betiği 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

20

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

du -scBM | sort -n

Bu, ölçeklenmiş değerler üretmez, ancak boyutu her zaman megabayt olarak oluşturur. Mükemmel olandan daha az, ama benim için hiç yoktan iyidir (veya boyutu bayt olarak gösterir).


Temelde -m ile aynı olan th -BM anahtarını beğendim, ancak boyut ve M üzerine eklenmiş M boyutlarını gösterme avantajına sahip, bu yüzden sadece 10'dan çok daha net olan 10M elde edersiniz :)
Tom Feiner

Bu, bu sayfada bugüne kadar gördüğüm en basit çözüm, teşekkür ederim!
Jeff Olson,

19

Bulunan bu ilanı başka bir yerde. Bu nedenle, bu kabuk betiği duher şeyi iki kere çağırmadan istediğinizi yapar . Bu kullanan awkbir insan tarafından okunabilir formata ham bayt dönüştürmek. Elbette, biçimlendirme biraz farklıdır (her şey bir ondalık basamak hassasiyetinde 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
}}}'

Bu benim .vimdizinde çalışan verim:

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

(3,6M renk şeması aşırı değildir umarım.)


1
Ben de bir Perl cevabım var, ama insanların benden nefret etmesine neden olabileceğini düşünüyorum: du -B1 | sort -nr | perl -e '% h = (0 => b, 1 => K, 2 => M, 3 => G); (<>) {($ s, @ f) = split / \ s + /; $ e = 3; $ e-- süre (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 cevabı gerçekte biçimlendirmesini duya çok daha fazla yaklaştırsa bile. Yuvarlama kapalı olmasına rağmen ... Görünüşe göre du her zaman yuvarlak () yerine tavan () verir
Adam Bellaire

Hey, neden orada bir karma kullandım? Bir dizi olmalıydı ... sabah beyni huysuz ....
Adam Bellaire

Başka bir cevap olarak daha iyi bir Perl çözümü eklendi.
Adam Bellaire

Dosya adları boşluk içerdiğinde her iki sürüm de başarısız olur
Vi.

15

Bu sürüm, awksıralama tuşları için fazladan sütun oluşturmak için kullanır . Sadece bir dukez arar . Çıktı tam olarak benzemelidir du.

Birden çok satıra ayırdım, ancak tek bir astarda 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 - K, M, G yerine 1, 2, 3 yerine 1, 2, 3'ten küçük bir ünite varsa, birimler yoksa (boyut 1K'dan küçükse), eşleşme olmaz ve sıfır döndürülür (mükemmel! )
  • yeni alanları yazdır - birim, değer (alfa sıralamasının sıfır dolgulu, sabit uzunlukta olması için düzgün çalışması için) ve orijinal satır
  • boyut alanının son karakterini indeksle
  • boyutun sayısal kısmını çıkarmak
  • sonuçları sırala, fazladan sütunları at

cutNe yaptığını görmek için komut olmadan deneyin .

İşte AWK komut dosyasında sıralama yapan ve gerekmeyen bir sürüm 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]]}'

teşekkür ederim! OS X 10.6'da benim için çalışan ilk örnek perl / phython-scriptleri saymamak. ve iyi bir açıklama için tekrar teşekkürler. yeni bir şeyler öğrenmek her zaman güzeldir. awk kesinlikle güçlü bir araçtır.
Wolf,

Bunun için çok teşekkürler. du -sh *Duyarlı özyinelemeden sadece hemen dosyaları ve dizinleri gösterecek du du değiştirdim .
HankCa

15

İşte dizinleri daha kompakt ve özetlenmiş bir biçimde 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

1
macOS / OSX kullanıcıları, xargs'ın mac sürümünün -d bayrağını desteklemediği konusunda uyarılırlar ve eğer bunu ihmal ederseniz, boşluk içeren dizinlerin her biri elbette başarısız olan her bir sözcüğü ayrı ayrı ayrıştırdığı konusunda uyarılır.
jasonology

11

dosyaları MB olarak boyuta göre sırala

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

9

Dutop için dutop adında basit ama kullanışlı bir python sarmalayıcı var . Biz (coreutils yöneticileri) "insan" çıktısını doğrudan sıralamak için bir işlevsellik eklemeyi düşünüyoruz.


1
"Bir şeyi yap ve doğru yap" için nadir, geçerli istisnalardan biri için +1. Birisi SI önekini ve / veya ikili önekleri anlamak için sıralama yapmazsa.
Joachim Sauer

Ve ptman'ın da belirttiği gibi: ta da ! (yeni sortbayrak)
Tobu

9

Başka bir tane daha var:

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

Perl'den hoşlanmaya başladım. Yapmak zorunda kalabilirsiniz

$ cpan Number::Bytes::Human

ilk. Dışarıdaki tüm perl hacker'larına: Evet, sıralama bölümünün perl'de de yapılabileceğini biliyorum. Muhtemelen du kısmı da.


8

Bu snippet, http://www.unix.com/shell-programming-scripting/32555-du-h-sort.html adresinden 'Jean-Pierre' den utanmaz bir şekilde geçti . Ona daha iyi kredi verebileceğim bir yol 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;
     }
    '

çok büyük bir sayı ise, o zaman birim gitti ve görüntülenen sayı küçükse ... try23423423432423
nopole 22:15

7

"-G" bayrağını kullanın

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

Ve / usr / local dizininde şöyle çıktı üretir:

$ 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
Bu, insan tarafından okunabilir bir çıktı vermiyor, ancak OP'nin aradığı şey bu.

4

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

İşte 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

On line on bulundu ... işe yarayacak 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

Gevşek bir şekilde bu bir astar, insan tarafından okunabilen, sıralanmış bir du (1) çıktısı sağlamak için bir komut dosyası oluşturdum. Lütfen cevabımı okuyunuz , serverfault.com/a/937459/218692 .
Tripp Kinetics

3

Dün bu örneği uyuşturmaktan çok şey öğrendim. Biraz zaman aldı, ama çok eğlenceliydi ve awk kullanmayı öğrendim.

Sadece bir kez du çalıştırır ve du-h'ye çok benzer bir çıktısı vardır.

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 nokta ile 10'un altındaki sayıları gösterir.


3

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


2

Boşluk kullanmanız gerekirse, 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örlerdeki sorunları gidermeye yardımcı olur


Bunu sadece MacOS Sierra'da denedim. Beklendiği gibi çalışır. Güzel!
jasonology

1

Voilà:

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

1

http://dev.yorhel.nl/ncdu

komut: ncdu

Dizin gezinme, sıralama (ad ve boyut), grafik oluşturma, okunabilir insan, vb ...


1
Harika bir yardımcı program, ancak bildiğim işletim sistemlerinde varsayılan olarak yüklü değil. Mutlaka bir sorun değil, ama sonra bakmak için bir program daha ...
voretaq7

1

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

@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ğil. 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);
}'

BSD du -d 1sözdizimi, GNU du tarafından desteklenmiştir, çünkü 8.6.0 2010'da piyasaya sürülmüştür (ilk Red Hat kullanılabilirliği 2014'te RHEL 7 idi), bu nedenle artık ihtiyacınız yok --maxdepth=1. Bunu son zamanlarda kendim öğrendim .
Adam Katz


1

Burada, çoğu yinelenen birçok cevap var. Üç eğilim görüyorum: ikinci bir du çağrısı aracılığıyla boru bağlantısı yapmak, karmaşık kabuk / awk kodu kullanmak ve diğer dilleri kullanmak.

İşte olan POSIX uyumlu çözüm kullanarak du ve awk her sistem üzerinde çalışması gerekir.

-xAynı dosya sisteminde kalmamızı sağlamak için ekleyerek biraz farklı bir yaklaşım izledim (bu diske çok az yer kapladığımda sadece bu işleme ihtiyacım var, bu yüzden neden bu FS ağacının içine yerleştirdiğim veya taşındığım ve geri bağlanmış?) ve görsel ayrıştırmayı kolaylaştırmak için sabit birimler gösteriliyor. Bu durumda, genellikle sıralama yapmamayı tercih ederim, böylece hiyerarşik yapıyı daha iyi görebilirim.

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

(Bu tutarlı birimlerinde olduğundan, daha sonra ekleyebilirsiniz | sort -nEğer gerçekten isterseniz sıralama ed sonuçları.)

Bu, (kümülatif) içeriği 512 MB'ı geçmeyen dizgileri filtreler ve ardından boyutları gigabayt olarak görüntüler. Varsayılan olarak, du 512 bayt blok boyutunu kullanır (bu yüzden 2 awk durumu 20 bloktan 512MB ve onun 2 21 - Kullanabileceğimiz bölen GB birimleri dönüştürür du -kxile $1 > 512*1024ve s/1024^2daha insan tarafından okunabilir olması için). Awk koşulunun içinde, sboyuta ayarlıyoruz böylece satırdan ( $0) kaldırabiliriz . Bu, sınırlayıcıyı (tek bir boşluğa daraltılmış olan) korur, bu nedenle final %s, bir boşluğu ve daha sonra toplanan direktörün adını temsil eder. %7syuvarlatılmış %.2fGB boyutunu hizalar ( %8s> 10TB'niz varsa artırın ).

Buradaki çözümlerin çoğundan farklı olarak, bu, adlarında boşluk bulunan dizinleri doğru şekilde destekler (bunun da dahil her çözüm, satır sonları içeren dizin adlarını yanlış yönlendirir).


0

En azından her zamanki araçlarla, insan tarafından okunabilen sayıların formatı nedeniyle bu zor olacak (sayıları sıraladığı için bu türün "iyi bir iş" yaptığını unutmayın - 508, 64, 61, 2, 2 - kayan nokta sayılarını ek çarpan ile sıralayamazsınız).

Bunu tam tersi şekilde denerdim - çıktısını "du | sort -n -r" kullanarak kullanın ve daha sonra bazı komut dosyası veya programlarla sayıları insan tarafından okunabilir formata dönüştürün.


0

Ne deneyebilirsiniz:

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

Umarım yardımcı olur.



hehe, her zaman xargs'ı unuturum. ;) Günün sonunda, ne iş yaparsa yapsın imo.

MacOSX varsayılan olarak (örn. Ev demiri dışında) uygun bir desteği desteklemediğinden xargsbu form gerekliydi. Ancak içinde boşluk bulunan dosyalar için IFS'yi ayarlamanız gerekir:IFS=$'\n'
HankCa

0
du | sort -nr | awk '{ cmd = "du -h -d0 "$2"| cut -f1"; cmd | getline human; close(cmd); print human"\t"$2 }'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.