Как вы сортируете вывод по размеру?

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
xenoterracide
источник
Принятый ответ sort -hсработал для меня в Ubuntu 16.04 LTS в августе 2017 года. Сначала я нашел свой смонтированный диск cd /mnt(смонтированный UUID в fstab). Затем я делаю, du >~/dumnt.out затем sort -h ~/dumnt.out >~/dumntsort.outмогу сделать `tail ~ / dumntsort.out, чтобы увидеть самых больших космических свиней.
SDsolar

Ответы:

252

Если у вас есть GNU coreutils (обычно в большинстве дистрибутивов Linux), вы можете использовать

du -sh -- * | sort -h

-hОпция указывает , sortчто вход является человеком-читаемый формат (номер с блоком; 1024 на основе , так что 1023 считается менее 1K , которое происходит соответствует тому , что GNU du -hделает).

Эта функция была добавлена ​​в GNU Core Utilities 7.5 в августе 2009 года .

Примечание:

Если вы используете более старую версию Mac OSX, вам нужно установить coreutils с помощью ,, а brew install coreutilsзатем использовать его gsortкак замену sort.

Более новые версии macOS (проверено на Mojave) sort -hизначально поддерживают .

Шон Дж. Гофф
источник
27
примечание: добавьте -rк сортировке, если хотите, чтобы большие были вверху
ксенотеррацид
9
В OSX вы можете установить coreutilsчерез brewи добавить папку bin PATHв свой файл rc , и она -hдолжна быть доступна.
kenorb
О, спасибо за напоминание. это означает, что мне не нужна tailкоманда, чтобы увидеть свиней.
SDsolar
47

Попробуйте использовать флаг -k для подсчета блоков размером в 1 КБ, понятных человеку. Тогда у вас есть общая единица и вы можете легко выполнить числовую сортировку.

du -ck | sort -n

Вы явно не требуете человеческих юнитов, но если вы это сделали, то есть множество способов сделать это. Многие, кажется, используют вышеописанную технику блока 1K, а затем делают второй вызов du.

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

Если вы хотите увидеть добавленные единицы КБ, используйте:

du -k | sed -e 's_^\([0-9]*\)_\1 KB_' | sort -n
pboin
источник
2
хорошо, что не нужно устанавливать что-то еще, чтобы получить нужные мне результаты
taranaki
16

Если у вас нет последней версии GNU coreutils , вы можете вызывать duбез -hнее, чтобы получить сортируемый вывод, и создать удобный для пользователя вывод с небольшой постобработкой. Это имеет преимущество работы, даже если ваша версия 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 (т. Е. Были кратны 1000, а не 1024), измените 1024 на 1000 в whileтеле цикла. (Обратите внимание, что это 1000 в условии предназначено, так что вы получите, например, 1Mа не 1000k.)

Если у вас duесть возможность отображать размеры в байтах (например, -bили -B 1- обратите внимание, что это может иметь побочный эффект при подсчете фактических размеров файлов, а не использования диска), добавьте пробел в начале s(то есть s=" kMGTEPYZ";) или добавьте if (x<1000) {return x} else {x/=1024}в начале humanфункция.

Отображение десятичной цифры для чисел в диапазоне 1–10 оставлено читателю в качестве упражнения.

жилль
источник
Это единственное решение, которое я нашел для работы на Linux и Mac. Большое спасибо!
Брайан Грэм
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 добавляет разделитель между цифрой и суффиксом. Третий седь преобразует G в Z, так что он больше, чем M; если у вас есть терабайтные файлы, вам придется конвертировать G в Y и T в Z. Наконец, мы сортируем по двум столбцам, затем заменяем суффикс G.

Шон Дж. Гофф
источник
Потрясающие усилия, но это не близко к работе на меня.
15:05
6

На OS X вы можете установить необходимые coreutils через Homebrew :

brew install coreutils

С этим у вас будет gsort, что включает в себя параметр -hкомандной строки.

Roland
источник
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;
ddeimeke
источник
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) или gawk, и все они работали.

Вот пример вывода на 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 *

nopole
источник
1

Вот что я использую в Ubuntu 10.04, CentOS 5.5, FreeBSD и Mac OS X.

Я позаимствовал эту идею у www.geekology.co.za/ и earthinfo.org , а также печально известных уток из «Linux Server Hacks» О'Рейли. Я все еще приспосабливаю это к своим потребностям. Это все еще в стадии разработки (как, я работал над этим в поезде этим утром.):

#! /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 *? (со звездочкой)
нополь
Звездочка избыточна в этом использовании. Попробуйте.
Стефан Ласевский,
Вы хотите поместить первый набор кода в файл с именем 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 }'
friedl.otto
источник
0

Он обрабатывает имена файлов с пробелами или апострофами и работает в системах, которые не поддерживают 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: это можно использовать для сортировки по любому столбцу, но значения этого столбца должны быть в том же формате

user5337995
источник
1
Номер sort -k1rnэквивалентен sort -rnи просто сортирует численно на основе начальной последовательности десятичных цифр в каждой строке. Он не понимает , с плавающей точкой, и она не понимает k, M, G... суффиксы. 10.1k будет считаться больше, чем 1.23G
Стефан
0

Проверено на солярисе!

du -kh | sort -nk1 | grep [0-9]K && du -kh | sort -nk1 | grep [0-9]M && du -kh | sort -nk1 | grep [0-9]G

Это приведет к рекурсивному выводу всех размеров каталогов, внизу будет самый большой каталог в гигабайтах, а вверху самый маленький в килобайтах.

Chuguniy
источник
0

Самое большое внизу:

du -sh * | sort -h
Meskan
источник
0

Команда:

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

Объяснение:

  • Размер списка всех файлов / папок рекурсивно в текущем каталоге в удобочитаемой форме

du -ah .

  • Сортируйте удобочитаемый размер, который присутствует в первом столбце, и оставьте наибольшее 50

sort -k1 -h | tail -n 50

Рохан Гиге
источник
-1

Сортировать по размеру в МБ

du --block-size=MiB --max-depth=1 path | sort -n
lukmansh
источник
Пользователь хочет получить результаты du -h(удобочитаемые выходные данные), отсортированные численно. Вы не даете ответ на это. Вы также можете связать свою учетную запись UNIX-SE с другими учетными записями, которые есть на других сайтах SE.
Тонин
-2

Этот скрипт еще проще:

for i in G M K; do du -h -d1 / | grep [0-9]$i | sort -n; done
Hobit
источник
-2

для OSX

du -h -k  {PATH} | sort -n
Стив Гринсайдс
источник
это не -kпросто отмена, -hи если да, то как это обеспечивает удобочитаемый вывод, запрошенный OP.
Anthon