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

<p>мне нужно, чтобы получить список читаемых человеком выводов.</p><p>однако <code>du</code> не имеет опции "сортировать по размеру", а конвейерная передача к <code>sort</code> не работает с понятным для человека флагом.</p><p>например, работает:</p><pre><code>du | sort -n -r </code></pre><p>выводит отсортированное использование диска по размеру (по убыванию):</p><pre><code>du |sort -n -r 65108 . 61508 ./dir3 2056 ./dir4 1032 ./dir1 508 ./dir2 </code></pre><p>тем не менее, запуск его с понятным для человека флагом не сортирует должным образом:</p><pre><code>du -h | sort -n -r 508k ./dir2 64m . 61m ./dir3 2.1m ./dir4 1.1m ./dir1 </code></pre><p>кто-нибудь знает способ сортировки <code>du -h</code> по размеру?</p>

<p>начиная с <a href="http://article.gmane.org/gmane.comp.gnu.core-utils.announce/52">gnu coreutils 7.5</a> , выпущенного в августе 2009 года, <code>sort</code> допускает параметр \_<code>-h</code>\_, который допускает числовые суффиксы типа, создаваемого \_<code>du -h</code>\_:</p><pre>\_<code>du -hs * | sort -h </code>\_</pre><p>если вы используете сортировку, которая не поддерживает \_<code>-h</code>\_, вы можете установить gnu coreutils. например, на более старой mac os x:</p><pre>\_<code>brew install coreutils du -hs * | gsort -h </code>\_</pre><p>от <code>sort</code> <a href="https://linux.die.net/man/1/sort">вручную</a> :</p><p><code>-h, --human-numeric-sort compare human readable numbers (e.g., 2k 1g)</code></p>

<pre><code>du | sort -nr | cut -f2- | xargs du -hs </code></pre>

<p>@ дуглас лидер, еще один ответ: сортируйте удобочитаемый вывод от du -h, используя другой инструмент. нравится perl!</p><pre><code>du -h | perl -e 'sub h{%h=(k=>10,m=>20,g=>30);($n,$u)=shift=~/([0-9.]+)(\d)/; return $n2$h{$u}}print sort{h($b)<=>h($a)}<>;' разделите на две строки, чтобы соответствовать дисплею. вы можете использовать его таким образом или сделать его однострочным, он будет работать в любом случае.вывод:4.5m . 3.7m ./colors 372k ./plugin 128k ./autoload 100k ./doc 100k ./syntax <strong> редактировать: </strong> после нескольких раундов игры в гольф в <a href="http://www.perlmonks.org/?node_id=746356">perlmonks , окончательный результат будет следующим:perl -e'%h=map{/.s/;99(ord$&&7)-$,$\_}`du -h`;die@h{sort%h}' </code></pre>

<p>существует очень полезный инструмент, который я использую, называемый <a href="http://dev.yorhel.nl/ncdu/">ncd</a> , который предназначен для поиска этих надоедливых папок и файлов с высоким уровнем использования диска и их удаления. он консольный, быстрый и легкий, и имеет пакеты для всех основных дистрибутивов.</p>

<pre><code>du -k * | sort -nr | cut -f2 | xargs -d '\n' du -sh </code></pre>

<p>насколько я вижу, у вас есть три варианта:</p><ol> <li>измените <code>du</code> для сортировки перед отображением.</li> <li>измените <code>sort</code> для поддержки размеров человека для числовой сортировки.</li> <li>выполните обработку вывода из сортировки, чтобы изменить базовый вывод на удобочитаемый.</li> </ol><p>вы также можете сделать <code>du -k</code> и жить с размерами в киб.</p><p>для варианта 3 вы можете использовать следующий скрипт:</p><pre><code>#!/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 

у меня также была эта проблема, и я в настоящее время использую обходной путь:du -scbm | sort -n это не приведет к получению масштабированных значений, но всегда даст размер в мегабайтах. это менее чем идеально, но для меня это лучше, чем ничего (или отображение размера в байтах).

найдено <a href="http://www.linuxquestions.org/questions/programming-9/gawkawktcsh-how-to-convert-large-number-to-human-readable-mbgb-etc-597921/">эта публикация в другом месте. следовательно, этот сценарий оболочки будет делать то, что вы хотите, не вызывая 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 цветовых схем не является чрезмерным.)

эта версия использует awk для создания дополнительных столбцов для ключей сортировки. он вызывает du только один раз. вывод должен выглядеть в точности как du.я разбил его на несколько строк, но он может быть объединен в одну строку.du -h | awk '{printf "%s %08.2ft%sn", index("kmg", substr($1, length($1))), substr($1, 0, length($1)-1), $0}' | sort -r | cut -f2,3 </code></pre><p>объяснение:</p><ul> <li>начало - создать строку для индексации, чтобы заменить 1, 2, 3 на k, m, g для группировки по единицам, если нет единицы (размер меньше 1 кб), то совпадения нет, и возвращается ноль (отлично! )</li> <li>напечатать новые поля - единицу измерения, значение (для правильной работы альфа-сортировки, с добавлением нуля, фиксированной длины) и исходную строку</li> <li>индексировать последний символ поля размера</li> <li>вытащить числовую часть размера</li> <li>сортировать результаты, отбрасывать лишние столбцы</li> </ul><p>попробуйте это без команды <code>cut</code>, чтобы увидеть, что она делает.</p><p>вот версия, которая выполняет сортировку в скрипте awk и не нуждается в <code>cut</code>:</p><pre><code>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]]}' </code></pre>

<p>вот пример, который показывает каталоги в более краткой форме. он обрабатывает пробелы в каталоге/именах файлов.</p><pre><code>% 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 </code></pre>

<p>сортировать файлы по размеру в мегабайтах</p><pre><code>du --block-size=mib --max-depth=1 path | sort -n </code></pre>

<p>у меня есть простая, но полезная python для du с названием <a href="http://www.pixelbeat.org/scripts/dutop">dutop</a> . обратите внимание, что мы (сопровождающие coreutils) рассматриваем возможность добавления функции сортировки для сортировки "человек"). вывод напрямую.</p>

<p>есть еще один:</p><pre><code>$ du -b1 | sort -nr | perl -mnumber::bytes::human=format_bytes -f't' -lane 'print format_bytes($f[0])."\t".$f[1]' мне начинает нравиться perl. возможно, вам придется сделать$ cpan number::bytes::human </code></pre><p>первый. всем хакерам perl: да, я знаю, что сортировку можно выполнить и в perl. вероятно, часть ду тоже.</p>

<p>этот фрагмент был бесстыдно заимствован из "жан-пьера" из <a href="http://www.unix.com/shell-programming-scripting/32555-du-h-sort.html">http://www.unix.com/shell-programming-scripting/32555-du-h-sort.html</a> . есть ли способ, которым я могу лучше кредитовать его?</p><pre><code>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; } ' </code></pre>

<p>используйте флаг "-g"</p><pre><code> -g, --general-numeric-sort compare according to general numerical value </code></pre><p>и в моем каталоге/usr/local выдает следующий результат:</p><pre><code>$ 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 

нашел этот на линии ... кажется, работает нормально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 

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

я узнал awk от придумывания этого примера вчера. это заняло некоторое время, но это было очень весело, и я научился пользоваться awk.он запускается только du один раз, и его вывод очень похож на du -hdu --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 }' показывает числа ниже 10 с одним десятичным знаком.

другой: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 } <>' 

du -cka --max-глубина = 1/var/log | сортировать -rn | голова -10 | awk '{print ($ 1)/1024, "мб", $ 2'}

если вам нужно обрабатывать пробелы, вы можете использовать следующее du -d 1| sort -nr | cut -f2 | sed 's/ / /g' | xargs du -sh дополнительный оператор sed поможет устранить проблемы с папками с такими именами, как поддержка приложений

вуаля:du -sk /var/log/ | sort -rn | awk '{print $2}' | xargs -ia du -hs "a" </code></pre>

<p>здесь много ответов, многие из которых являются дубликатами. я вижу три тенденции: прохождение второго звонка, использование сложного кода shell/awk и использование других языков.</p><p>вот <strong> posix-совместимое решение </strong> с использованием <a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/du.html">d</a> и <a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html">awk</a> , которое должно работать в любой системе.</p><p>я выбрал немного другой подход, добавив <code>-x</code> чтобы убедиться, что мы остаемся в одной файловой системе (эта операция нужна мне только тогда, когда у меня мало места на диске, поэтому зачем отсеивать то, что я смонтировал в этом дереве fs или переехал) и символическую ссылку назад?) и отображение постоянных единиц для упрощения визуального анализа. в этом случае я обычно выбираю <em> нет</em> для сортировки, чтобы лучше видеть иерархическую структуру.</p><pre><code>sudo du -x | awk ' $1 > 2^20 { s=$1; $1=""; printf "%7sg%sn", sprintf("%.2f",s/2^21), $0 }' </code></pre><p>(так как это в последовательных единицах, вы можете добавить <code>| sort -n</code> если вы действительно хотите <a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sort.html">сортировать</a> редактировать результаты.)</p><p>это отфильтровывает любой каталог, чье (совокупное) содержимое не может превышать 512 мб, а затем отображает размеры в гигабайтах. по умолчанию du использует размер блока 512 байт (поэтому условие awk равно 2<sup>20</sup> блоков 512mb и его 2<sup>21</sup> делитель преобразует единицы в гб - мы могли бы использовать <code>du -kx</code> с <code>$1 > 5121024 а также s/1024^2 чтобы быть более читабельным). внутри условия awk мы устанавливаем размер s, чтобы мы могли удалить его из строки ($0</code>). это сохраняет разделитель (который свернут в один пробел), поэтому окончательный <code>%s</code> представляет пробел, а затем имя агрегированного каталога. <code>%7s</code> выравнивает округлые <code>%.2f</code> размер гб (увеличить до <code>%8s</code> если у вас> 10 тб).</p><p>в отличие от большинства решений здесь, <strong> это правильно поддерживает каталоги с пробелами в их именах </strong> (хотя <em> every</em> решение, включая это один, будет неправильно обрабатывать имена каталогов, содержащие разрывы строк).</p>

<p>другое <code>awk</code> решение -</p><pre><code>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 

 <a href="http://dev.yorhel.nl/ncdu">http://dev.yorhel.nl/ncd команда: ncduнавигация по каталогам, сортировка (имя и размер), графики, удобочитаемые и т.д.

я использовал решение, предоставленное @ptman, но недавнее изменение сервера сделало его более нежизнеспособным. вместо этого я использую следующий скрипт bash:#!/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<10241024) printf("%.1f mbt%s",$1/1024,$2); else printf("%.1f gbt%s",$1/1024/1024,$2); }' 

<blockquote> ду-с  | сортировать -nr | cut -f2 | xargs du -sh </blockquote>

вот примерdu -h /folder/subfolder --max-depth=1 | sort -hr возвращает:233m /folder/subfolder 190m /folder/subfolder/myfolder1 15m /folder/subfolder/myfolder4 6.4m /folder/subfolder/myfolder5 4.2m /folder/subfolder/myfolder3 3.8m /folder/subfolder/myfolder2 вы также можете добавить | head -10 чтобы найти топ-10 или любое количество подпапок в указанном каталоге.

это псевдоним, который я имею в .profile<blockquote> псевдоним du = 'sudo du -xh --max-глубина = 1 | сортировать </blockquote>сортировка -h это то, что действительно помогает здесь на вопрос.другие полезные опции - du -x, чтобы остаться в той же файловой системе; также sudo помогает не видеть ошибок, если есть каталоги, которые не доступны для чтения всем пользователям. кроме того, я всегда делаю du --max-deep = 1, затем углубляюсь и т.д.

еще один сценарий du!поскольку уже есть много ответов, я просто публикую свой собственный сценарий там. я использую с более чем восьми лет.это может быть запущено/somepath/rdu.sh [-b] [/somepath] [minsize] где необязательный флаг -b указать использовать <strong>  количество байтов  </strong> вместо <strong>  количество блоков  </strong> необязательный  путь  в качестве 1-го аргумента, текущий каталог по умолчанию. если второй аргумент не указан, минимальный размер для печати равен <strong>  256mb  </strong>. вывод может выглядеть так:___ 3.01g 21.67% .cache | ___ 1.37g 45.54% mozilla | | ___ 1.37g 100.00% firefox | | | ___ 581.71m 41.48% billiethek.default | | | | ___ 522.64m 89.85% cache2 | | | | | ___ 522.45m 99.96% entries ... есть скрипт:#!/bin/bash if [ "$1" == "-b" ] ;then shift units=(b k m g t p) duargs="-xbs" minsize=${2:-$((256*1024**2))} else units=(k m g t p) duargs="-xks" minsize=${2:-$((256*1024))} fi humansize() { local \_c=$1 _i=0 while [ ${#\_c} -gt 3 ] ;do ((\_i++)) \_c=$((_c>>10)) done _c=$(( ( $11000 ) >> ( 10_i ) )) printf ${2+-v} $2 "%.2f%s" ${\_c:0:${#_c}-3}.${\_c:${#_c}-3} ${units[\_i]} } percent() { local p=000$((${1}00000/$2)) printf ${3+-v} $3 "%.2f%%" ${p:0:${#p}-3}.${p:${#p}-3} } device=$(stat -c %d "${1:-.}") printf -v sep "%16s" "" rdu() { local _dir="$1" \_spc="$2" _crt _siz _str _tot _pct while read _siz _crt;do if [ "$\_crt" = "total" ]; then \_tot=$_siz else [ "$\_tot" ] || \_tot=$_siz if [ $\_siz -gt $minsize ];then humansize $\_siz \_str percent $_siz $\_tot \_pct printf "%s\\_\_\_ %7s%s%7s%s%s\n" \ "$_spc" $\_str "$sep" $\_pct "$sep" "${\_crt##*/}" [ -d "$_crt" ] && [ $(stat -c %d "$_crt") -eq $device ] && rdu "$_crt" "| $\_spc" fi fi done < <( find "$_dir" -mindepth 1 -maxdepth 1 -xdev  ( -type f -o -type d ) -printf "%d;%pn" | sed -ne "s/^${device};//p" | tr \\n \\0 | xargs -0 du ${duargs}c | sort -nr ) } rdu "${1:-.}" </code></pre><p>и нет, я не буду публиковать их на <em> <code>git***.xxx</code> </em>.</p><p>вы можете <a href="https://www.f-hauri.ch/vrac/rdu.sh.txt">показать их там</a> или <a href="https://www.f-hauri.ch/vrac/rdu.sh">скачать скрипт там.</a> </p>

<p>вот мое решение, простой bash-скрипт, который вызывает du только один раз и показывает вам только каталоги размером 1 мб или больше:</p><pre><code>#!/bin/env bash # usage: my\_du.sh [subdirectory levels] # for efficiency, only calls "du" once, and stores results in a temp file # stephen becker, 2/23/2010 if [ $# -gt 0 ]; then # you may prefer, as i do, to just summarize the contents of a directory # and not view the size of its subdirectories, so use this: du -h --max-depth $1 > temp\_du\_file else du -h > temp\_du\_file fi # show all directories of size > 1 gb: cat temp\_du\_file | grep "^\([0-9]\|\.\)\+g" | sort -nr # show all directories of size > 1 mb: cat temp\_du\_file | grep "^\([0-9]\|\.\)\+m" | sort -nr rm temp\_du\_file </code></pre>

<p>по крайней мере, с обычными инструментами это будет сложно из-за формата, в котором читаемые человеком цифры (обратите внимание, что сортировка делает "хорошую работу" здесь, так как сортирует числа - 508, 64, 61, 2, 2 - это просто не могу отсортировать числа с плавающей запятой с дополнительным множителем).</p><p>я бы попробовал все наоборот - использовать вывод из "du | sort -n -r" и затем преобразовать числа в понятный человеку формат с помощью некоторого сценария или программы.</p>

<p>что вы можете попробовать это:</p><pre><code>for i in `du -s * | sort -n | cut -f2` do du -h $i; done надеюсь, это поможет.

du | sort -nr | awk '{ cmd = "du -h -d0 "$2"| cut -f1"; cmd | getline human; close(cmd); print human"\t"$2 }' 

следующее решение похоже на оригинал cadrian, однако оно будет запускать только две команды du, а не одну du для каждого каталога в дереве.du -hs du |sort -g |cut -f2-  однако решение кардриана является более надежным, поскольку вышеприведенное не будет работать для очень густонаселенных деревьев, так как оно может превысить ограничение на размер аргументов, передаваемых du

основываясь на логике в <a href="https://serverfault.com/a/93204/218692">этот однострочный , я написал скрипт, который предоставляет отсортированный читаемый человеком вывод du (1). кроме того, что требуется -h флаг для удобочитаемости, он не требует никаких других не posix-совместимых команд.он доступен по адресу <a href="https://github.com/pleappleappleap/sorted-human-du">https://github.com/pleappleappleap/sorted-human-d .

почему бы не бросить еще одну шляпу в кольцо ... это старый вопрос, но вот пример, который (в основном) представляет собой чистый сценарий shell (fwiw) - то есть, просто bash, а не perl/python/awk/и т.д. так что в этом смысле, может быть, он предлагает что-то новое для обсуждения (или нет). он рассчитывает размер файла только один раз, но печатает в различных единицах (мои предпочтения). (неупрощенная версия включает в себя getopts, который исключает "гб", если это нежелательно.)#!/bin/bash printf -- ' %9s %9s %9s %-30sn' 'k' 'm' 'g' 'path' printf -- ' %9s %9s %9s %-30sn' '--------' '--------' '--------' '-----------' du -sk "$@" | while read val; do file=$(echo "$val" | cut -f2-) size\_k=$(echo "$val" | cut -f1) printf ' %9s %9s %9s %-30s\n' \ ${size_k}  $(( size\_k / 1024 )) \ $(( size_k / 1024 / 1024 ))  "$file" done | sort -n </code></pre>

<p>сортировка по убыванию.</p><pre><code>du -s ./* | sort -n| cut -f 2-| xargs du -sh {} </code></pre>