Vraag Hoe kan ik de uitvoer van de -h sorteren op grootte


Ik moet een lijst van menselijke leesbare du-uitvoer krijgen.

Echter, du heeft geen "op soort" -optie en gaat naar sort werkt niet met de menselijk leesbare vlag.

Bijvoorbeeld: uitvoeren:

du | sort -n -r 

Voert een gesorteerd schijfgebruik uit volgens grootte (aflopend):

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

Het wordt echter niet correct gesorteerd als het wordt uitgevoerd met de menselijk leesbare vlag:

du -h | sort -n -r

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

Weet iemand een manier om te sorteren du -h  op maat?


830
2018-02-25 13:42


oorsprong


Heh ... Grappig dat je dat zou moeten vragen, omdat dit me vervelend deed zijn ... tenminste een jaar lang. Vorige week heb ik de code gedownload naar GNU coreutils (waarvan soort een onderdeel is), en heb een kijkje genomen, maar besloot dat het wat langer zou duren dan ik op mijn handen had om te patchen ... Iemand? :) - unwind
Hier is een veelverwante vraag: serverfault.com/q/737537/35034 - cregox
Heb je deze al gezien? unix.stackexchange.com/questions/4681/...  Het is bijna een duplicaat en is goud waard. Je doet een normaal du maar voeg de -h toe aan de sort commando. Je kan toevoegen -rh dus de grootste zijn de eerste in het bestand, anders heb je dat nodig tail om de ruimvarkens te zien. - SDsolar
Ik had niet verwacht dat zo'n vraag zo populair zou zijn toen ik dit googelde. - Mateen Ulhaq


antwoorden:


Vanaf GNU coreutils 7.5 uitgebracht in augustus 2009, sort staat een -h parameter, die numerieke achtervoegsels mogelijk maakt van de soort die wordt geproduceerd door du -h:

du -hs * | sort -h

Als u een soort gebruikt die niet wordt ondersteund -h, je kunt GNU Coreutils installeren. Bijv. op een ouder Mac OS X:

brew install coreutils
du -hs * | gsort -h

Van sort met de hand:

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


1152
2017-07-01 12:29



Het relevante gedeelte van de handleiding: gnu.org/software/coreutils/manual/... - wodow
Eenvoudig te installeren op OS X met homebrew - brew coreutils installeren. - Richard Poirier
Een goede! Dat heb ik persoonlijk altijd gedaan du -BM | sort -nr als een tijdelijke oplossing - het is voldoende leesbaar voor de mens en het is gesorteerd, als iemand vastzit met oudere kernutils. - chutz
Als je via Homebrew op OSX gebruikt, merk dan op dat je nu gsort moet gebruiken in plaats van sorteren: du -hs * | gsort -h - Brian Cline
@PaulDraper, du -BM drukt alles in megabytes af, dus een bestand dat 168K is, wordt feitelijk weergegeven als 0M. Tenzij er een ander verschil in de versie is waar ik me niet van bewust ben. Mijn versie van du toont alleen megabytewaarden van gehele getallen. - chutz


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

82
2018-02-25 13:52



En het zal een enorme hoeveelheid dubbel tellen doen. - Douglas Leeder
Eerst doet het de normale du - daarna herberekent het voor elke invoer de grootte om het in een voor mensen leesbare vorm af te drukken. - Douglas Leeder
@Douglas Leeder: je hebt gelijk voor het dubbeltellen, maar denk dat de tweede du niet vanuit koude cache start (dankzij het besturingssysteem) @hasen j: xargs is een erg handig commando, het splitst zijn stdin en voert het als argumenten in naar de gegeven opdracht - cadrian
Chris is eigenlijk superieur omdat het werkt met paden die witruimte bevatten. Een stem op jouw manier gooien, vriend. - rbright
Lelijk, maar platformonafhankelijk :). - voretaq7


@Douglas Leeder, nog een antwoord: Sorteer de menselijk leesbare uitvoer van du-h met een ander gereedschap. Zoals 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)}<>;'

Splits op twee regels om op het scherm te passen. Je kunt het op deze manier gebruiken of het een one-liner maken, het zal hoe dan ook werken.

Output:

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

BEWERK: Na een paar rondjes golf over PerlMonks, het eindresultaat is het volgende:

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

59
2018-02-25 21:04



Uw korte versie wordt uitgevoerd stderr vanwege de die kun je het veranderen om het op te laten werken stdout? - Dennis Williamson
Verander de die naar een print en het zal gaan stdout. Het zijn nog maar twee tekens. - Adam Bellaire
werkt op ubuntu! - marinara
indrukwekkende perl hackistry - nandoP
Het resultaat is in omgekeerde volgorde :( - RSFalcon7


Er is een enorm bruikbare tool die ik gebruik genaamd ncdu die is ontworpen voor het vinden van die vervelende mappen en bestanden met een hoge schijfruimte en het verwijderen ervan. Het is gebaseerd op de console, snel en licht en heeft pakketten voor alle grote distributies.


50
2018-02-25 20:39



Erg leuk ... Ik vind het des te moeilijker om de resultaten standaard te voeden ... Ik ben zo lui dat ik de handleiding niet kan lezen - ojblass
GT5 is in dezelfde geest; zijn moordenaarse eigenschap toont groei. - Tobu
Dat is echt cool! En veel sneller dan rondhangen du, als u alleen de grote mappen wilt identificeren. - BurninLeo


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

43
2018-02-25 14:01



precies wat ik zocht, bedankt - Edward Tanguay
Kan niet gebruiken met du -k --total, geeft een fout aan het einde du: cannot access 'total': No such file or directory - laggingreflex
ik vind dit nog een ander antwoord. hoe zou je gaan om alleen de eerste 50 resultaten te tonen? - Mauro
@Mauro - pijp gewoon het resultaat naar head door `|. toe te voegen hoofd -50` aan het eind. - Samuel Lelièvre


Voor zover ik kan zien heb je drie opties:

  1. Wijzigen du om te sorteren voor weergave.
  2. Wijzigen sort om menselijke maten te ondersteunen voor numerieke sortering.
  3. Post de uitvoer van sorteren om de basisuitvoer in leesbaar voor mensen te veranderen.

Je zou ook kunnen doen du -k en leef met maten in KiB.

Voor optie 3 zou je het volgende script kunnen gebruiken:

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





Ik heb dat probleem ook gehad en ik gebruik momenteel een tijdelijke oplossing:

du -scBM | sort -n

Dit levert geen geschaalde waarden op, maar produceert altijd de grootte in megabytes. Dat is minder dan perfect, maar voor mij is het beter dan niets (of het weergeven van de grootte in bytes).


19
2018-02-25 13:56



Ik hou van th -BM-switch, wat in feite hetzelfde is als -m, maar het heeft het voordeel dat de grootte wordt weergegeven en dat er M achteraf op is geplaatst, dus je krijgt 10M, wat veel duidelijker is dan slechts 10 :) - Tom Feiner
Dit is de eenvoudigste oplossing die ik tot nu toe op deze pagina heb gezien, bedankt! - Jeff Olson


gevonden deze posting ergens anders. Daarom zal dit shellscript doen wat je wilt zonder te bellen du op alles twee keer. Het gebruikt awk om de onbewerkte bytes om te zetten in een voor mensen leesbaar formaat. Natuurlijk is de opmaak iets anders (alles wordt afgedrukt op één precisie na de komma).

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

Dit in mijn .vim map opbrengsten:

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

(Ik hoop dat 3,6 miljoen kleurenschema's niet overdreven zijn.)


18
2018-02-25 14:09



Ik heb ook een Perl-antwoord, maar ik denk dat mensen hierdoor me kunnen haten: du -B1 | sort -nr | perl -e '% h = (0 => b, 1 => K, 2 => M, 3 => G); for (<>) {($ s, @ f) = splitsen / \ 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
Hoewel het antwoord van Perl de opmaak veel dichter bij du geeft. Hoewel de afronding is uitgeschakeld ... Het lijkt erop dat du altijd ceil () geeft in plaats van round () - Adam Bellaire
Hé, waarom heb ik daar een hash gebruikt? Had een array moeten zijn ... ochtendhersenen mopperen.... - Adam Bellaire
Een betere Perl-oplossing toegevoegd als een ander antwoord. - Adam Bellaire
Beide versies werken niet als bestandsnamen spaties bevatten - Vi.


Deze versie gebruikt awk om extra kolommen voor sorteersleutels te maken. Het roept alleen du een keer. De uitvoer moet er precies zo uitzien du.

Ik heb het in meerdere lijnen gesplitst, maar het kan worden gecombineerd in een one-liner.

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

Uitleg:

  • BEGIN - maak een reeks om te indexeren om 1, 2, 3 te vervangen door K, M, G voor eenheden, als er geen eenheid is (de grootte is minder dan 1K), dan is er geen overeenkomst en wordt er een nul geretourneerd (perfect! )
  • print de nieuwe velden - eenheid, waarde (om de alfa-sortering correct te laten werken is deze nul opgevuld, van vaste lengte) en originele lijn
  • indexeer het laatste teken van het veld grootte
  • trek het numerieke deel van de grootte eruit
  • sorteer de resultaten, gooi de extra kolommen weg

Probeer het zonder de cut commando om te zien wat het doet.

Hier is een versie die het sorteren in het AWK-script uitvoert en niet nodig heeft 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



dank je! dit is het eerste voorbeeld dat voor mij werkt in OS X 10.6 zonder de perl / phython-scripts te tellen. en nogmaals bedankt voor de goede uitleg. altijd leuk om iets nieuws te leren. awk is zeker een krachtig hulpmiddel. - Wolf
Bedankt daarvoor. Ik veranderde de du in du -sh * om alleen de directe bestanden en mappen weer te geven zonder recursieve afkomst. - HankCa


Hier is een voorbeeld dat de mappen in een meer compacte samengevatte vorm toont. Het behandelt spaties in directory / bestandsnamen.

% 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

13
2018-03-18 22:10



macOS / OSX-gebruikers worden gewaarschuwd dat de mac-versie van xargs de vlag -d niet ondersteunt, en als u dit weglaat, hebben alle mappen die een spatie bevatten, elk woord apart geparseerd wat natuurlijk faalt. - jasonology


sorteer bestanden op grootte in MB

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

9
2017-09-04 08:10