คุณเรียงลำดับผลลัพธ์ตามขนาดอย่างไร


196

คุณจัดเรียงdu -sh /dir/*ตามขนาดได้อย่างไร ฉันอ่านเว็บไซต์หนึ่งที่กล่าวว่าใช้งาน| sort -nแต่เห็นได้ชัดว่าไม่ถูกต้อง นี่คือตัวอย่างที่ผิด

[~]# 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

3
ผมรู้ว่าผมต้องการเห็นนี้มาก่อน คำตอบที่ได้รับการโหวตสูงสุดมีไม่ดีมากแต่ คนอื่น ๆ อยู่ ที่ดีขึ้น
Gilles

คำตอบที่ได้รับการยอมรับนั้นsort -hใช้ได้กับฉันใน Ubuntu 16.04 LTS ในเดือนสิงหาคม 2017 ก่อนอื่นฉันต้องหาไดรฟ์ที่ติดตั้งโดยcd /mnt(ติดตั้งโดย UUID ใน fstab) จากนั้นฉันก็ทำเช่นdu >~/dumnt.out นั้นsort -h ~/dumnt.out >~/dumntsort.outฉันสามารถทำ `หาง ~ / dumntsort.out เพื่อดูหมูอวกาศที่ใหญ่ที่สุด
SDsolar

คำตอบ:


252

ถ้าคุณมี coreutils ของ GNU (พบได้ทั่วไปใน Linux ส่วนใหญ่) คุณสามารถใช้

du -sh -- * | sort -h

-hตัวเลือกที่จะบอกsortว่าการป้อนข้อมูลที่เป็นรูปแบบที่มนุษย์สามารถอ่านได้ (หมายเลขกับหน่วย; 1024 ตามเพื่อที่ 1023 ถือว่าน้อยกว่า 1K ที่เกิดขึ้นเพื่อให้ตรงกับสิ่งที่ GNU du -hไม่)

คุณลักษณะนี้ถูกบันทึกอยู่ใน GNU หลักสาธารณูปโภค 7.5 ในสิงหาคม 2009

บันทึก:

หากคุณกำลังใช้รุ่นเก่าของ Mac OSX, คุณต้องติดตั้ง coreutils ด้วยbrew install coreutilsแล้วใช้เป็นแบบเลื่อนแทนgsortsort

MacOS เวอร์ชันใหม่กว่า (ตรวจสอบแล้วใน Mojave) รองรับsort -hโดยกำเนิด


27
หมายเหตุ: เพิ่ม-rในการจัดเรียงถ้าคุณต้องการให้ชิ้นใหญ่อยู่ด้านบน
xenoterracide

9
บน OSX คุณสามารถติดตั้งcoreutilsผ่านbrewและเพิ่มโฟลเดอร์ bin PATHลงในไฟล์rcของคุณและ-hควรจะใช้ได้
kenorb

โอ้ - ขอบคุณสำหรับคำเตือน -r นั่นหมายความว่าฉันไม่ต้องการtailคำสั่งเพื่อดูหมู
SDsolar

47

ลองใช้แฟล็ก -k เพื่อนับจำนวนบล็อก 1K ที่ผู้อ่านสามารถอ่านได้ จากนั้นคุณมีหน่วยร่วมและสามารถเรียงลำดับตัวเลขได้อย่างง่ายดาย

du -ck | sort -n

คุณไม่ต้องใช้หน่วยของมนุษย์อย่างชัดเจน แต่ถ้าคุณทำคุณมีหลายวิธีที่จะทำ หลายคนดูเหมือนจะใช้เทคนิคบล็อก 1K ด้านบนแล้วทำการโทรครั้งที่สองเพื่อดู

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

หากคุณต้องการดูหน่วย KB ที่เพิ่มให้ใช้:

du -k | sed -e 's_^\([0-9]*\)_\1 KB_' | sort -n

2
ดีใจที่ไม่ต้องติดตั้งอย่างอื่นเพื่อให้ได้ผลลัพธ์ที่ฉันต้องการ
taranaki

16

หากคุณไม่มีcoreutils GNU รุ่นล่าสุดคุณสามารถโทรออกduโดยไม่ต้อง-hรับเอาต์พุตที่สามารถจัดเรียงได้และสร้างเอาต์พุตที่เป็นมิตรกับมนุษย์ด้วย postprocessing เล็กน้อย สิ่งนี้มีข้อดีของการทำงานแม้ว่าเวอร์ชันของคุณduจะไม่มีการ-hตั้งค่าสถานะ

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

หากคุณต้องการส่วนต่อท้ายของ SI (เช่นทวีคูณของ 1,000 แทนที่จะเป็น 1024) ให้เปลี่ยน 1024 เป็น 1,000 ในส่วนของwhileลูป (โปรดทราบว่ามีเงื่อนไข 1,000 ข้อเพื่อให้คุณได้รับเช่น1Mแทนที่จะเป็น1000k)

หากคุณduมีตัวเลือกในการแสดงขนาดเป็นไบต์ (เช่น-bหรือ-B 1- โปรดทราบว่านี่อาจมีผลข้างเคียงของการนับขนาดไฟล์จริงมากกว่าการใช้งานดิสก์) เพิ่มช่องว่างไปยังจุดเริ่มต้นของs(เช่นs=" kMGTEPYZ";) หรือเพิ่มif (x<1000) {return x} else {x/=1024}ที่จุดเริ่มต้นของhumanฟังก์ชั่น

การแสดงตัวเลขทศนิยมสำหรับตัวเลขในช่วงที่ 1–10 จะเป็นแบบฝึกหัดสำหรับผู้อ่าน


นี่เป็นโซลูชันตัวแรกที่ฉันพบว่าทำงานได้ทั้งบน linux และ mac ขอบคุณมาก ๆ!
Brian Graham

9

หากคุณไม่มีsort -hคุณสามารถทำได้:

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

นี่รับรายการ du คั่นส่วนต่อท้ายและเรียงลำดับการใช้ เนื่องจากไม่มีคำต่อท้ายสำหรับ <1K, sed แรกเพิ่ม B (สำหรับไบต์) sed ที่สองเพิ่มตัวคั่นระหว่างตัวเลขและคำต่อท้าย sed ที่สามแปลง G เป็น Z เพื่อให้ใหญ่กว่า M หากคุณมีไฟล์เทราไบต์คุณจะต้องแปลง G เป็น Y และ T เป็น Z ในที่สุดเราก็เรียงลำดับตามสองคอลัมน์จากนั้นเราแทนที่ G ต่อท้าย


ความพยายามยอดเยี่ยม แต่นี่ไม่ได้ใกล้เคียงกับการทำงานสำหรับฉัน
jvriesem

6

บน OS X คุณสามารถติดตั้ง coreutils ที่ต้องการผ่านHomebrew :

brew install coreutils

ด้วยสิ่งนี้คุณจะมีgsortซึ่งรวมถึง-hพารามิเตอร์บรรทัดคำสั่ง


4

สคริปต์ Perl นี้เล็กน้อยทำเคล็ดลับ บันทึกเป็นduh(หรืออะไรก็ได้ที่คุณต้องการ) แล้วโทรด้วยduh /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;

4

ตั้งแต่ Mac OS X ไม่มี-hตัวเลือกsortฉันเลยลองและเรียนรู้sedและawkลองครั้งแรก:

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

มันเป็นเส้นยาว ขยายตัวมันคือ:

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; 

}'

ฉันลองบน Mac OS X Mavericks, Yosemite, Ubuntu 2014-04 ด้วยawkการเป็นค่าเริ่มต้นawk(ซึ่งเป็นnawkเพราะawkและnawkชี้ไปที่/usr/bin/mawk) หรือเพ่งพิศและพวกเขาทั้งหมดทำงาน

นี่คือตัวอย่างของการส่งออกบน 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

แทนที่จะdu -sk *เห็นในคำตอบของ @ Stefan ที่แสดงผลรวมทั้งหมดและโดยไม่ข้ามจุดเมานต์ระบบไฟล์ใด ๆ โดยใช้du -skcx *


1

นี่คือสิ่งที่ฉันใช้บน Ubuntu 10.04, CentOS 5.5, FreeBSD และ Mac OS X

ฉันยืมความคิดจากwww.geekology.co.za/และearthinfo.orgรวมถึงเป็ดที่น่าอับอายจาก "Linux Server Hacks" โดย O'Reilly ฉันยังคงปรับให้เข้ากับความต้องการของฉัน นี่ยังเป็นงานที่กำลังดำเนินอยู่ (ในตอนนี้ฉันกำลังทำสิ่งนี้บนรถไฟเมื่อเช้านี้):

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

นี่คือผลลัพธ์:

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:~ $

ฉันคิดว่าคุณหมายถึงdu -cks -x *อะไร (พร้อมเครื่องหมายดอกจัน)
nopole

เครื่องหมายดอกจันซ้ำซ้อนในการใช้งานนี้ ให้มันลอง.
Stefan Lasiewski

คุณหมายถึงการวางรหัสชุดแรกลงในไฟล์ที่เรียกว่าducksจากchmod a+x ducksนั้นใช้./ducksเพื่อเรียกใช้หรือไม่ จากนั้นฉันเห็นการใช้งานดิสก์ทั้งหมดทั้งบน Mac OS X และบน Ubuntu 2014-10 ฉันยังพยายามใส่ducks() { ...}คำจำกัดความ.bashrcแล้วใช้ducksเพื่อเรียกใช้และสิ่งเดียวกันใน Mac OS X เห็นเฉพาะผลรวมทั้งหมด
nopole

1

เป็นบ้ากับสคริปต์นี้ -

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

1

ในกรณีที่ไม่มี GNU sort -hสิ่งนี้ควรทำงานในสภาพแวดล้อม 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 }'

0

อันนี้จัดการชื่อไฟล์ด้วย whitespace หรือ apostrophes และทำงานบนระบบที่ไม่รองรับxargs -dหรือsort -h:

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

ซึ่งผลลัพธ์ใน:

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

0

นี้จะเรียงลำดับผลลัพธ์ในการลดขนาด:

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

สิ่งนี้จะเรียงลำดับผลลัพธ์ในการเพิ่มขนาด:

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

PS: สิ่งนี้สามารถใช้ในการจัดเรียงตามคอลัมน์ใด ๆ แต่ค่าคอลัมน์นั้นควรอยู่ในรูปแบบเดียวกัน


1
ไม่sort -k1rnเท่ากับsort -rnและเพียงเรียงลำดับตัวเลขตามลำดับเริ่มต้นของตัวเลขทศนิยมในแต่ละบรรทัด มันไม่เข้าใจจุดลอยและก็ไม่เข้าใจk, M, G... ต่อท้าย 10.1k จะถือว่ามากกว่า 1.23G
Stéphane Chazelas

0

ทดสอบกับ 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

สิ่งนี้จะเอาท์พุทขนาดไดเรกทอรีทั้งหมดซ้ำ ๆ ที่ด้านล่างจะเป็นไดเรกทอรีที่ใหญ่ที่สุดในหน่วยกิกะไบต์และที่เล็กที่สุดในหน่วยกิโลไบต์



0

คำสั่ง:

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

คำอธิบาย:

  • ขนาดรายการของไฟล์ / โฟลเดอร์ทั้งหมดซ้ำในไดเรกทอรีปัจจุบันในรูปแบบที่มนุษย์สามารถอ่านได้

du -ah .

  • จัดเรียงขนาดที่มนุษย์สามารถอ่านได้ซึ่งมีอยู่ในคอลัมน์แรกและเก็บ 50 ที่ใหญ่ที่สุด

sort -k1 -h | tail -n 50


-1

เพื่อจัดเรียงตามขนาดเป็น MB

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

ผู้ใช้ต้องการรับเอาต์พุตของdu -h(เอาต์พุตที่มนุษย์สามารถอ่านได้) เรียงลำดับตัวเลข คุณไม่ได้ให้คำตอบสำหรับสิ่งนั้น คุณอาจต้องการเชื่อมโยงบัญชี UNIX-SE ของคุณกับบัญชีอื่น ๆ ที่คุณมีในเว็บไซต์ SE อื่น ๆ
Tonin


-2

สำหรับ OSX

du -h -k  {PATH} | sort -n

ไม่ใช่-kแค่การยกเลิก-hและถ้าเป็นเช่นนั้นจะให้เอาต์พุตที่มนุษย์สามารถอ่านได้ที่ร้องขอโดย OP
Anthon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.