du -h 출력을 크기별로 정렬하는 방법


966

사람이 읽을 수있는 du 출력 목록을 가져와야합니다.

그러나 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 크기별로 정렬하는 방법을 알고 있습니까?


Heh ... 웃기는 질문이 있습니다. 적어도 1 년이 넘게 나를 귀찮게했기 때문입니다. 지난주에 GNU coreutils에 코드를 다운로드하여 살펴 보았습니다.하지만 패치하는 데 시간이 좀 더 걸릴 것이라고 결정했습니다. :)
긴장을 풀고

관련 질문이 많이 있습니다 : serverfault.com/q/737537/35034
cregox

이거 봤어? unix.stackexchange.com/questions/4681/… 거의 복제본이며 금 가치가 있습니다. 정상적인 작업을 수행 du하지만 sort명령에 -h를 추가하십시오 . -rh파일에서 가장 큰 파일을 먼저 추가 할 수 있습니다 . 그렇지 않으면 tail스페이스 호그가 표시 되어야 합니다.
SDsolar

나는 이것을 구글 검색했을 때 그러한 질문이 그렇게 인기가 있기를 기대하지 않았다.
Mateen Ulhaq

답변:


1361

현재 GNU의로 coreutils 7.5 2009 년 8 월에 발표 sort-h에 의해 생성 된 종류의 숫자 접미사를 허용 매개 변수를 du -h:

du -hs * | sort -h

를 지원하지 않는 정렬을 사용하는 경우 -hGNU Coreutils를 설치할 수 있습니다. 예를 들어 이전 Mac OS X의 경우 :

brew install coreutils
du -hs * | gsort -h

에서 sort 수동 :

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


3
매뉴얼의 관련 섹션 : gnu.org/software/coreutils/manual/…
wodow

29
Homebrew를 사용하여 OS X에 쉽게 설치-BREW 설치 coreutils.
Richard Poirier

41
좋은 것! 나는 개인적으로 항상 du -BM | sort -nr해결 방법으로 일했습니다. 사람이 읽을 수 있으며 사람이 오래된 coreutils에 붙어 있으면 정렬됩니다.
chutz

30
Homebrew를 통해 OSX에서 사용하는 경우 이제 정렬 대신 gsort를 사용해야합니다.du -hs * | gsort -h
Brian Cline

2
@PaulDraper du -BM는 모든 것을 메가 바이트 단위로 인쇄하므로 168K 인 파일은 실제로 0M으로 표시됩니다. 내가 모르는 다른 버전의 불일치가 없으면. 내 버전 du은 정수 메가 바이트 값만 보여줍니다.
chutz

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

48
그리고 엄청난 양의 중복 계산을 수행합니다.
Douglas Leeder

1
먼저 정상적인 du를 수행 한 다음 각 항목마다 사람이 읽을 수있는 형식으로 인쇄하기 위해 크기를 다시 계산합니다.
Douglas Leeder

8
@ Douglas Leeder : 중복 계산에 적합하지만 두 번째 du는 콜드 캐시에서 시작되지 않는다고 생각합니다 (OS 덕분에) @hasen j : xargs는 매우 유용한 명령이며 stdin을 분할하여 인수로 제공합니다 주어진 명령에
cadrian

4
Chris는 공백을 포함하는 경로와 함께 작동하기 때문에 실제로 우수합니다. 당신의 방식으로 표를 던지십시오, 친구.
rbright

3
추악하지만 크로스 플랫폼 :).
voretaq7

62

@Douglas Leeder, 또 하나의 대답 : 다른 도구를 사용하여 du-h에서 사람이 읽을 수있는 출력을 정렬하십시오. 펄처럼!

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

2
당신 이 그것을 출력하도록 변경 할 수 stderr있기 때문에 짧은 버전이 출력 됩니까? diestdout
Dennis Williamson

2
로 변경하면 dieprint이동합니다 stdout. 두 글자 만 더 있습니다.
Adam Bellaire

우분투에서 작동합니다!
marinara

인상적인 perl hackistry
nandoP

결과는 역순입니다. (
RSFalcon7

55

디스크 사용량이 많은 폴더와 파일을 찾아서 제거하기 위해 설계된 ncdu 라는 매우 유용한 도구 가 있습니다. 콘솔 기반이며 빠르고 가벼우 며 모든 주요 배포판에 패키지가 있습니다.


아주 좋은 ... 결과가 표준 출력으로 공급 될 수 있다면 나는 이겼다 ... 나는 너무 게으르다 매뉴얼을 읽을 수 없습니다
ojblass

8
gt5 는 동일한 정맥에 있으며; 킬러 기능이 성장하고 있습니다.
Tobu

1
정말 멋지다! du큰 디렉토리를 식별하려는 경우 와 함께하는 것보다 훨씬 빠릅니다 .
BurninLeo

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

사용할 수 없음 du -k --total, 마지막에 오류가 있습니다du: cannot access 'total': No such file or directory
laggingreflex

나는이 다른 답변을 더 좋아합니다. 처음 50 개의 결과 만 어떻게 표시 하시겠습니까?
Mau

1
@Mauro- head`| 끝에 머리 -50`.
Samuel Lelièvre 2019

21

내가 알 수있는 한 세 가지 옵션이 있습니다.

  1. du표시하기 전에 정렬을 변경하십시오 .
  2. sort숫자 정렬을 위해 사람 크기를 지원하도록 변경하십시오 .
  3. 출력을 사후 처리하여 기본 출력을 사람이 읽을 수 있도록 변경합니다.

du -kKiB에서 크기를 가지고 생활 할 수도 있습니다 .

옵션 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

나는 그 문제도 있었고 현재 해결 방법을 사용하고 있습니다 :

du -scBM | sort -n

이렇게하면 크기 조정 된 값이 생성되지 않지만 항상 크기 (MB)가 생성됩니다. 그것은 덜 완벽하지만 나에게는 아무것도 아닌 것보다 낫습니다 (또는 크기를 바이트 단위로 표시).


나는 기본적으로 -m과 동일한 th-BM 스위치를 좋아하지만 크기와 M을 접두사로 표시하는 이점이 있으므로 10M을 얻습니다 .10보다 훨씬 명확합니다 :)
Tom Feiner

이 페이지에서 지금까지 본 가장 간단한 솔루션입니다. 감사합니다!
Jeff Olson

19

다른 곳 에서이 게시물을 찾았습니다 . 따라서이 쉘 스크립트는 du모든 것을 두 번 호출하지 않고 원하는 것을 수행합니다. awk원시 바이트를 사람이 읽을 수있는 형식으로 변환하는 데 사용 됩니다. 물론 서식은 약간 다릅니다 (모든 것은 소수점 이하 자릿수 1 자리로 인쇄 됨).

#/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의 색 구성표가 과도하지 않기를 바랍니다.)


1
나도 펄 답변을 받았지만 사람들이 나를 미워하게 할 수도 있다고 생각한다 : du -B1 | 정렬 -nr | perl -e '% h = (0 => b, 1 => K, 2 => M, 3 => G); for (<>) {($ s, @ f) = split / \ s + /; $ e = 3; $ e-- 동안 (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에 훨씬 가까운 형식을 제공합니다. 반올림이 꺼져 있지만 뒤 항상 천장을 만들다 ()보다는 라운드 ()를 제공합니다처럼 ... 그것은 본다
아담 벨레

왜 해시를 사용 했습니까? 배열 이었어 야했는데 ... 아침 뇌 불평이 ....
Adam Bellaire

다른 답변으로 더 나은 Perl 솔루션을 추가했습니다.
Adam Bellaire

파일 이름에 공백이 있으면 두 버전 모두 실패합니다
.

15

이 버전은 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-단위별로 그룹화를 위해 K, M, G 대신 1, 2, 3을 대체 할 색인을 생성 할 문자열을 작성하십시오. 단위가 없으면 (크기가 1K 미만) 일치하지 않고 0이 리턴됩니다 (완벽! )
  • 새로운 필드-단위, 값 (알파 정렬이 제대로 작동하도록하기 위해 0으로 채워진 고정 길이 임)과 원래 줄을 인쇄하십시오.
  • 크기 필드의 마지막 문자를 색인
  • 크기의 숫자 부분을 당겨
  • 결과 정렬, 추가 열 삭제

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

감사합니다! 이것은 perl / phython-scripts를 세지 않고 OS X 10.6에서 작동하는 첫 번째 예입니다. 좋은 설명 감사합니다. 항상 새로운 것을 배우는 것이 좋습니다. 확실히 강력한 도구입니다.
늑대

감사합니다. 나는 du -sh *재귀 하강없이 즉각적인 파일과 디렉토리 만 표시 하도록 du를 변경했습니다 .
HankCa

15

다음은 디렉토리를보다 간결한 요약 형식으로 표시하는 예입니다. 디렉토리 / 파일 이름의 공백을 처리합니다.

% 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

1
macOS / OSX 사용자는 xargs의 mac 버전이 -d 플래그를 지원하지 않는다는 경고를 표시하며, 생략하면 공백이 포함 된 디렉토리는 각각의 단어가 개별적으로 구문 분석되며 실패합니다.
jasonology

11

크기를 MB 단위로 파일 정렬

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

9

나는 뒤의 간단하지만 유용한 파이썬 래퍼라고했습니다 dutop . 우리 (coreutils 유지 관리자)는 "인간"출력을 직접 정렬하기 위해 정렬하는 기능 추가를 고려하고 있습니다.


1
"한 가지만하고 올바르게 수행"하는 드문 유효 예외 중 하나에 +1. 누군가가 SI 접두사 및 / 또는 이진 접두사를 이해하는 데 익숙하지 않으면.
Joachim Sauer

그리고 ptman이 아래에 언급 한 것처럼 : ta da ! (새로운 sort깃발)
Tobu

9

또 하나있어 :

$ du -B1 | sort -nr | perl -MNumber::Bytes::Human=format_bytes -F'\t' -lane 'print format_bytes($F[0])."\t".$F[1]'

나는 펄을 좋아하기 시작했다. 당신은해야 할 수도 있습니다

$ cpan Number::Bytes::Human

먼저. 모든 펄 해커들에게 : 예, 나는 정렬 부분도 펄에서 수행 될 수 있다는 것을 알고 있습니다. 아마 뒤 부분 일 것입니다.


8

이 스 니펫은 http://www.unix.com/shell-programming-scripting/32555-du-h-sort.html의 'Jean-Pierre'에서 부끄러워하지 않았습니다 . 내가 더 잘 신용 할 수있는 방법이 있습니까?

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

나는 그것이 매우 큰 숫자라면, 그 단위는 사라지고 표시되는 숫자는 작다고 생각합니다 ... try23423423432423
nopole

7

"-g"플래그를 사용하십시오

 -g, --general-numeric-sort
              compare according to general numerical value

그리고 내 / usr / local 디렉토리에서 다음과 같은 출력을 생성합니다.

$ 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

4
그러나 인간이 읽을 수있는 출력을 제공하지는 않지만 OP가 찾고있는 것입니다.

4

다른 것:

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

4

여기에 내가 사용하는 간단한 방법, 매우 낮은 리소스 사용량이 있으며 필요한 것을 얻을 수 있습니다.

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

4

이것을 온라인에서 찾았습니다 ... 작동하는 것 같습니다

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 (1) 출력을 제공하는 스크립트를 만들었습니다. 내 답변 serverfault.com/a/937459/218692를 참조하십시오 .
Tripp Kinetics

3

나는 어제이 예를 구체화함으로써 어색함을 배웠다. 시간이 좀 걸렸지 만 재미 있었고 awk 사용법을 배웠습니다.

du를 한 번만 실행하며 du -h와 매우 유사한 출력을 갖습니다.

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

소수점 이하 1 자리로 10 미만의 숫자를 표시합니다.


3

du -cka --max-depth = 1 / var / log | 정렬 -rn | 머리 -10 | awk '{print ($ 1) / 1024, "MB", $ 2'}


2

공백을 처리 해야하는 경우 다음을 사용할 수 있습니다

 du -d 1| sort -nr | cut -f2 | sed 's/ /\\ /g' | xargs du -sh

추가 sed 문은 응용 프로그램 지원과 같은 이름을 가진 폴더의 문제를 완화하는 데 도움이됩니다.


macOS Sierra에서 이것을 시도했습니다. 예상대로 작동합니다. 좋은!
jasonology



1

또 다른 awk해결책-

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

1

@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<1024*1024)
    printf("%.1f MB\t%s",$1/1024,$2);
else
    printf("%.1f GB\t%s",$1/1024/1024,$2);
}'

BSD du -d 1구문은 coreutils 8.6이 2010 년에 릴리스 된 이후 (2014 년의 첫 번째 Red Hat 가용성은 RHEL 7이지만) 더 이상 필요하지 않은 GNU du에서 지원되었습니다 --maxdepth=1. 나는 최근에 이것에 대해서만 알게되었습니다 .
Adam Katz


1

여기에 많은 답변이 있으며, 그중 다수는 중복입니다. 세 번째 경향 : 두 번째 이중 호출을 통한 파이핑, 복잡한 쉘 / awk 코드 사용 및 기타 언어 사용이 있습니다.

다음은 모든 시스템에서 작동해야하는 duawk 를 사용 하는 POSIX 호환 솔루션 입니다.

-x우리는 동일한 파일 시스템을 유지하기 위해 약간 다른 접근 방식을 취했습니다. (디스크 공간이 부족할 때만이 작업이 필요 하므로이 FS 트리에 마운트하거나 이동하고 시각적으로 쉽게 구문 분석 할 수 있도록 상수 단위를 표시합니다. 이 경우 일반적으로 정렬 하지 않기 때문에 계층 구조를 더 잘 볼 수 있습니다.

sudo du -x | awk '
  $1 > 2^20 { s=$1; $1=""; printf "%7sG%s\n", sprintf("%.2f",s/2^21), $0 }'

(이는 일관된 단위이므로 정렬 된 결과를 | sort -n원한다면 추가 할 수 있습니다 .)

이렇게하면 (누적) 컨텐츠가 512MB를 초과하지 않는 디렉토리를 필터링 한 다음 크기 (GB)를 표시합니다. 기본적으로 뒤이 512 바이트 블록 크기를 사용합니다 (그래서 2 개의 AWK의 상태 20 블록 512MB의이고 그것의 2 (21) - 우리가 사용할 수있는 제수는 기가 바이트 단위 변환 du -kx$1 > 512*1024그리고 s/1024^2더 읽을 수). awk 조건 내에서 s크기를 설정 하여 행에서 제거 할 수 있습니다 ( $0). 이것은 분리 문자 (단일 공백으로 축소됨)를 유지하므로 마지막 %s은 공백을 나타내고 집계 된 디렉토리의 이름을 나타냅니다. %7s둥근 %.2fGB 크기를 정렬합니다 ( %8s> 10TB가있는 경우 증가 ).

여기에있는 대부분의 솔루션과 달리, 이름에 공백이있는 디렉토리를 올바르게 지원합니다 ( 이 솔루션을 포함한 모든 솔루션은 줄 바꿈이 포함 된 디렉토리 이름을 잘못 처리합니다).


0

적어도 일반적인 도구를 사용하면 사람이 읽을 수있는 숫자 형식이기 때문에 어려울 것입니다 (정렬은 숫자를 정렬함에 따라 "좋은 일"을합니다-508, 64, 61, 2, 2-it 추가 승수로 부동 소수점 숫자를 정렬 할 수는 없습니다).

다른 방법으로 시도해보십시오. "du | sort -n -r"의 출력을 사용하고 나중에 스크립트 또는 프로그램을 사용하여 숫자를 사람이 읽을 수있는 형식으로 변환하십시오.


0

시도 할 수있는 것은 :

for i in `du -s * | sort -n | cut -f2`
do
  du -h $i;
done

희망이 도움이됩니다.


그것이 xargs
가하는

hehe, 나는 항상 xargs를 잊어 버린다. ;) 하루가 끝날 무렵, 작업을 수행하는 모든 것은 imo입니다.

기본적으로 MacOSX (예 :자가 맥주 외부)는 적절한 xargs형식을 지원하지 않으므로이 양식이 필요했습니다. 그러나 공백이있는 파일의 경우 IFS를 설정해야합니다.IFS=$'\n'
HankCa

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.