Вопрос: Как я могу сортировать du -h вывод по размеру


Мне нужно получить список доступных для чтения людей.

Однако, du не имеет опции «сортировать по размеру» и sort не работает с человеческим читаемым флагом.

Например, запуск:

du | sort -n -r 

Выводит сортированное использование диска по размеру (по убыванию):

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

Однако, запустив его с помощью считываемого человеком флага, он не сортируется должным образом:

du -h | sort -n -r

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

Кто-нибудь знает способ сортировки du -h  по размеру?


790
2018-02-25 13:42


Источник


Хе-хе ... Забавно, что ты должен спросить, так как это меня раздражало ... как минимум, на год. На прошлой неделе я загрузил код в GNU coreutils (какой сорт является частью), и посмотрел, но решил, что потребуется немного больше времени, чем у меня на руках, чтобы заплатить ... Кто-нибудь? :) - unwind
Вот очень близкий вопрос: serverfault.com/q/737537/35034 - cregox
Вы видели это? unix.stackexchange.com/questions/4681/...  Это почти дубликат и стоит золота. Вы делаете нормальный du но добавьте -h к sort команда. Можете добавить -rh поэтому самые большие сначала в файле, иначе вам нужно tail чтобы увидеть космические свиньи. - SDsolar
Я не ожидал, что такой вопрос будет настолько популярен, когда я пойду в Google. - Mateen Ulhaq


Ответы:


Начиная с GNU coreutils 7.5 выпущенный в августе 2009 года, sort позволяет -h параметр, который позволяет использовать числовые суффиксы типа, созданного du -h:

du -hs * | sort -h

Если вы используете сортировку, которая не поддерживает -h, вы можете установить GNU Coreutils. Например. на старшей Mac OS X:

brew install coreutils
du -hs * | gsort -h

Из sort руководство:

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


1106
2017-07-01 12:29



Соответствующий раздел руководства: gnu.org/software/coreutils/manual/... - wodow
Прост в установке на OS X с домашней установкой Coreutils. - Richard Poirier
Неплохо! Я лично всегда делал du -BM | sort -nr как обходной путь - он достаточно читабель для человека, и он сортируется, если кто-то застрял с более старыми ядрами. - chutz
Если вы используете OSX через Homebrew, обратите внимание, что теперь вам нужно будет использовать gsort, а не sort: du -hs * | gsort -h - Brian Cline
@PaulDraper, du -BM печатает все в мегабайтах, поэтому файл размером 168K будет отображаться как 0M. Если не существует какой-либо другой несоответствия версии, о которой я не знаю. Моя версия du только показывает целочисленные значения мегабайта. - chutz


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

80
2018-02-25 13:52



И он будет делать огромное количество дублированных подсчетов. - Douglas Leeder
Сначала он выполняет обычное du - тогда для каждой записи он пересчитывает размер только для его распечатки в удобочитаемой форме. - Douglas Leeder
@Douglas Leeder: вы правы для повторного подсчета голосов, но думайте, что второй du не начинается с холодного кеша (благодаря ОС) @hasen j: xargs - очень полезная команда, она разбивает свой stdin и передает его как аргументы к данной команде - cadrian
Крис действительно превосходит его, поскольку он работает с путями, содержащими пробелы. Бросайте свой голос, приятель. - rbright
Уродливый, но кроссплатформенный :). - voretaq7


@Douglas Leeder, еще один ответ: Сортируйте удобочитаемый результат с du -h с помощью другого инструмента. Как 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)}<>;'

Разделите на две линии, чтобы они соответствовали дисплею. Вы можете использовать его таким образом или сделать его одним лайнером, он будет работать в любом случае.

Вывод:

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

РЕДАКТИРОВАТЬ: После нескольких раундов игры в гольф на PerlMonks, конечный результат следующий:

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

56
2018-02-25 21:04



Ваша короткая версия выводится на stderr из-за die можете ли вы изменить его, чтобы он выводился на stdout? - Dennis Williamson
Изменить die к print и он перейдет к stdout, Это всего лишь два персонажа. - Adam Bellaire
работает на ubuntu! - marinara
впечатляющий хакерство perl - nandoP
Результат в обратном порядке :( - RSFalcon7


Существует очень полезный инструмент, который я использую ncdu который предназначен для поиска этих досадных папок и файлов с большим объемом диска и их удаления. Он основан на консоли, быстрый и легкий, и имеет пакеты на всех основных дистрибутивах.


49
2018-02-25 20:39



Очень приятно ... Мне не повезло, если бы результаты могли быть доведены до стандартного ... Я настолько ленив, что не могу прочитать руководство - ojblass
gt5 находится в том же духе; его функция убийцы демонстрирует рост. - Tobu
Это действительно здорово! И гораздо быстрее, чем болтаться с du, если вы просто хотите идентифицировать большие каталоги. - BurninLeo


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

42
2018-02-25 14:01



только то, что я искал благодаря - Edward Tanguay
Нельзя использовать с du -k --total, дает ошибку в конце du: cannot access 'total': No such file or directory - laggingreflex
Мне нравится еще один ответ. как бы вы пошли, чтобы показать только первые 50 результатов? - Mauro
@Mauro - просто проведите результат до head добавив `| head -50` в конце. - Samuel Lelièvre


Насколько я вижу, у вас есть три варианта:

  1. изменять du для сортировки перед отображением.
  2. изменять sort для поддержки размеров человека для численного сортирования.
  3. Постобразить выход из сортировки, чтобы изменить основной вывод на человеко-читаемый.

Вы также можете сделать du -k и жить с размерами в KiB.

Для варианта 3 вы можете использовать следующий скрипт:

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





У меня тоже была эта проблема, и в настоящее время я использую обходной путь:

du -scBM | sort -n

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


19
2018-02-25 13:56



Мне нравится th -BM-переключатель, который в основном такой же, как -m, но он имеет то преимущество, что отображает размер и M, добавленные к нему, поэтому вы получаете 10M, который намного яснее, чем 10 :) - Tom Feiner
Это самое простое решение, которое я видел до сих пор на этой странице, спасибо! - Jeff Olson


Найденный это сообщение в другом месте. Поэтому этот сценарий оболочки будет делать то, что вы хотите, без вызова du на все два раза. Оно использует awk для преобразования необработанных байтов в удобочитаемый формат. Конечно, форматирование немного отличается (все печатается с точностью до десяти знаков).

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

Запуск этого в моем .vim выход каталога:

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

(Надеюсь, 3.6M цветовых схем не является чрезмерным.)


18
2018-02-25 14:09



У меня также есть ответ Perl, но я думаю, что это может заставить людей ненавидеть меня: du -B1 | sort -nr | perl -e '% h = (0 => b, 1 => K, 2 => M, 3 => G), для (<>) {($ 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
Несмотря на то, что ответ Perl фактически дает свое форматирование гораздо ближе к du. Хотя округление выключено ... Похоже, что du всегда дает ceil (), а не round () - Adam Bellaire
Эй, почему я использовал хэш там? Должна быть массив ... утренний мозг ворчать.... - Adam Bellaire
В качестве другого ответа добавлено лучшее решение для Perl. - Adam Bellaire
Обе версии не работают, когда имена файлов содержат пробелы - Vi.


Эта версия использует awk для создания дополнительных столбцов для ключей сортировки. Он звонит только du один раз. Результат должен выглядеть точно так же, как du,

Я разделил его на несколько строк, но его можно объединить в однострочный.

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

Объяснение:

  • BEGIN - создать строку для индексации для замены 1, 2, 3 для K, M, G для группировки по единицам, если нет единицы (размер меньше 1K), тогда нет совпадения и возвращается нуль (отлично! )
  • напечатайте новые поля - единица измерения, значение (чтобы обработка альфа-сортировки работала правильно, она была заполнена нулями, фиксированная длина) и исходной строкой
  • индекс последнего символа поля размера
  • вытащите цифровую часть размера
  • сортировать результаты, отбрасывать дополнительные столбцы

Попробуйте это без cut чтобы увидеть, что он делает.

Вот версия, которая выполняет сортировку по сценарию AWK и не нужна 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



Спасибо! это первый пример, который работает для меня в OS X 10.6, не считая perl / phython-scripts. и еще раз спасибо за хорошее объяснение. всегда приятно узнать что-то новое. awk sure - мощный инструмент. - Wolf
Большое спасибо за это. Я изменил дю на du -sh * для отображения только непосредственных файлов и каталогов без рекурсивного спуска. - HankCa