Pertanyaan Bagaimana saya bisa mengurutkan output du -h berdasarkan ukuran


Saya perlu mendapatkan daftar output du yang dapat dibaca manusia.

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

Misalnya, menjalankan:

du | sort -n -r 

Menghasilkan 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 memilah dengan baik:

du -h | sort -n -r

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

Apakah ada yang tahu cara untuk mengurutkan du -h  menurut ukuran?


830
2018-02-25 13:42




Heh ... Lucu, kamu harus bertanya, karena ini telah menjengkelkanku ... setidaknya setahun lebih. Minggu lalu saya mengunduh kode ke GNU coreutils (yang semacam itu adalah bagian), dan melihat-lihat, tetapi memutuskan itu akan membutuhkan waktu sedikit lebih lama daripada yang ada di tangan saya untuk menambal ... Siapa saja? :) - unwind
Inilah pertanyaan yang sangat terkait: serverfault.com/q/737537/35034 - cregox
Pernahkah Anda melihat yang ini? unix.stackexchange.com/questions/4681/…  Ini adalah duplikat dekat dan bernilai emas. Anda melakukan hal yang normal du tetapi tambahkan -h ke sort perintah. Anda dapat menambahkan -rh jadi yang terbesar adalah yang pertama di file, jika tidak, Anda perlu tail untuk melihat ruang babi. - SDsolar
Saya tidak menyangka pertanyaan seperti itu akan menjadi sangat populer ketika saya melakukan googling ini. - Mateen Ulhaq


Jawaban:


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

du -hs * | sort -h

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

brew install coreutils
du -hs * | gsort -h

Dari sort manual:

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


1152
2017-07-01 12:29



Bagian yang relevan dari manual: gnu.org/software/coreutils/manual/… - wodow
Mudah diinstal pada OS X dengan homebrew - menginstal coreutils. - Richard Poirier
Bagus sekali! Saya pribadi selalu melakukannya du -BM | sort -nr sebagai solusi - itu adalah manusia cukup mudah dibaca, dan itu diurutkan, jika ada yang terjebak dengan coreutils yang lebih tua. - chutz
Jika menggunakan OSX melalui Homebrew, perhatikan bahwa Anda sekarang harus menggunakan gsort daripada mengurutkan: du -hs * | gsort -h - Brian Cline
@PaulDraper, du -BM mencetak semuanya dalam megabyte, sehingga file yang berukuran 168K akan benar-benar ditampilkan sebagai 0M. Kecuali ada beberapa perbedaan versi lain yang tidak saya sadari. Versi saya dari du hanya menampilkan nilai integer megabyte. - chutz


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

82
2018-02-25 13:52



Dan itu akan melakukan sejumlah besar penghitungan duplikat. - Douglas Leeder
Pertama ia melakukan du normal - kemudian untuk setiap entri menghitung ulang ukuran hanya untuk mencetaknya dalam bentuk yang dapat dibaca manusia. - Douglas Leeder
@Douglas Leeder: Anda benar untuk penghitungan duplikat, tetapi berpikir bahwa du kedua tidak mulai dari cache dingin (terima kasih kepada OS) @hassen j: xargs adalah perintah yang sangat berguna, ia membagi stdinnya dan memasukkannya sebagai argumen ke perintah yang diberikan - cadrian
Chris sebenarnya lebih unggul karena bekerja dengan jalur yang mengandung spasi. Melempar suara dengan cara Anda, kawan. - rbright
Jelek, tapi cross-platform :). - voretaq7


@Douglas Leeder, satu jawaban lagi: Urutkan keluaran 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)}<>;'

Pisahkan ke dua garis agar sesuai dengan tampilan. Anda dapat menggunakannya dengan cara ini atau membuatnya menjadi satu-liner, itu akan bekerja dengan baik.

Keluaran:

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

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

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

59
2018-02-25 21:04



Versi pendek Anda menghasilkan stderr karena itu die dapatkah Anda mengubahnya untuk membuatnya menjadi output stdout? - Dennis Williamson
Mengubah die ke a print dan itu akan pergi ke stdout. Itu hanya dua karakter lagi. - Adam Bellaire
bekerja di ubuntu! - marinara
perl permen yang mengesankan - nandoP
Hasilnya adalah urutan terbalik :( - RSFalcon7


Ada alat yang sangat berguna yang saya gunakan disebut ncdu yang dirancang untuk menemukan folder dan file-file dengan penggunaan disk tinggi yang mengganggu, dan menghapusnya. Ini berbasis konsol, cepat dan ringan, dan memiliki paket pada semua distro utama.


50
2018-02-25 20:39



Sangat menyenangkan ... Saya bertanya-tanya apakah hasilnya dapat diberikan kepada standar ... Saya sangat malas sehingga saya tidak dapat membaca manual - ojblass
gt5 berada dalam nada yang sama; fitur pembunuhnya menampilkan pertumbuhan. - Tobu
Itu keren sekali! Dan jauh lebih cepat daripada bergaul dengan du, jika Anda hanya ingin mengidentifikasi direktori besar. - BurninLeo


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

43
2018-02-25 14:01



hanya apa yang saya cari terima kasih - Edward Tanguay
Tidak bisa digunakan dengan du -k --total, memberi kesalahan di bagian akhir du: cannot access 'total': No such file or directory - laggingreflex
Saya suka yang satu ini lagi jawaban lainnya. bagaimana Anda akan pergi untuk hanya menampilkan 50 hasil pertama? - Mauro
@Mauro - cukup salurkan hasilnya head dengan menambahkan `| kepala -50` di bagian akhir. - Samuel Lelièvre


Sejauh yang saya bisa lihat, Anda memiliki tiga opsi:

  1. Mengubah du untuk mengurutkan sebelum ditampilkan.
  2. Mengubah sort untuk mendukung ukuran manusia untuk jenis numerik.
  3. Post proses output dari mengurutkan untuk mengubah output dasar ke manusia yang dapat dibaca.

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

Untuk opsi 3 Anda bisa 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

20
2018-02-25 13:53





Saya memiliki masalah itu juga dan saat ini saya menggunakan solusi:

du -scBM | sort -n

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


19
2018-02-25 13:56



Saya suka th -BM switch, yang pada dasarnya sama dengan -m, tetapi memiliki keuntungan menampilkan ukuran dan M postfixed untuk itu, sehingga Anda mendapatkan 10M yang jauh lebih jelas daripada hanya 10 :) - Tom Feiner
Ini adalah solusi paling sederhana yang pernah saya lihat sejauh ini di halaman ini, terima kasih! - Jeff Olson


Ditemukan posting ini di tempat lain. Oleh karena itu, skrip shell ini akan melakukan apa yang Anda inginkan tanpa panggilan du pada segalanya dua kali. Itu menggunakan awk untuk mengkonversi byte mentah ke format yang dapat dibaca manusia. Tentu saja, formatnya sedikit berbeda (semuanya dicetak pada satu presisi desimal).

#/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 saya .vim hasil direktori:

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

(Saya harap 3.6M skema warna tidak berlebihan.)


18
2018-02-25 14:09



Saya juga memiliki jawaban Perl, tetapi saya pikir itu mungkin membuat orang membenci saya: du-B1 | urutkan -nr | perl -e '% h = (0 => b, 1 => K, 2 => M, 3 => G); untuk (<>) {($ s, @ f) = split / \ s + /; $ e = 3; $ e-- while (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
Meskipun jawaban Perl benar-benar memberikan formatnya lebih dekat ke du. Meskipun pembulatan mati ... Sepertinya du selalu memberikan ceil () daripada bulat () - Adam Bellaire
Hei, mengapa saya menggunakan hash di sana? Seharusnya menjadi array ... otak pagi ngomel.... - Adam Bellaire
Ditambahkan solusi Perl yang lebih baik sebagai jawaban lain. - Adam Bellaire
Kedua versi gagal ketika nama file mengandung spasi - Vi.


Versi ini menggunakan awk untuk membuat kolom tambahan untuk mengurutkan kunci. Itu hanya panggilan du sekali. Outputnya akan terlihat persis seperti itu du.

Saya telah membaginya menjadi beberapa baris, tetapi dapat digabungkan menjadi satu baris.

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 alfa-sort bekerja dengan benar, itu adalah zero-padded, fixed-length) dan garis asli
  • indeks karakter terakhir dari bidang ukuran
  • tarik keluar bagian numerik dari ukuran
  • semacam hasil, buang kolom tambahan

Cobalah tanpa cut perintah untuk melihat apa yang dilakukannya.

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

14
2017-09-04 17:06



Terima kasih! ini adalah contoh pertama yang bekerja untuk saya di OS X 10.6 tidak termasuk skrip perl / phython. dan terima kasih sekali lagi atas penjelasan yang baik. selalu senang belajar sesuatu yang baru. awk yakin adalah alat yang kuat. - Wolf
Terima kasih banyak untuk itu. Saya mengubah du ke du -sh * untuk hanya menampilkan file dan direktori langsung tanpa penurunan rekursif. - HankCa


Berikut contoh yang menunjukkan direktori dalam bentuk ringkasan yang lebih ringkas. 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

13
2018-03-18 22:10



Pengguna macOS / OSX diperingatkan bahwa versi mac xargs tidak mendukung flag -d, dan jika Anda mengabaikannya, direktori apa pun yang berisi ruang memiliki setiap kata yang diurai secara terpisah yang tentu saja gagal. - jasonology


urutkan file berdasarkan ukuran dalam MB

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

9
2017-09-04 08:10