Question Comment puis-je trier la sortie du -h par taille


J'ai besoin d'une liste de résultats lisibles par l'homme.

cependant, du n’a pas d’option de "tri par taille" et de tuyauterie vers sort ne fonctionne pas avec le drapeau lisible par l'homme.

Par exemple, en cours d'exécution:

du | sort -n -r 

Produit une utilisation du disque trié par taille (décroissant):

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

Cependant, l’exécuter avec le drapeau lisible par l’homme ne trie pas correctement:

du -h | sort -n -r

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

Est-ce que quelqu'un connaît un moyen de trier du -h  par taille?


830
2018-02-25 13:42


origine


Heh ... C'est drôle, demandez-vous, car cela m'agace depuis ... bien au moins un an. La semaine dernière, j'ai téléchargé le code dans GNU Coreutils (dont une partie fait partie) et j’ai jeté un coup d’œil, mais j’ai décidé que cela prendrait un peu plus de temps que de le patcher pour mettre à jour ... Tout le monde? :) - unwind
Voici une question très liée: serverfault.com/q/737537/35034 - cregox
As-tu vu celui-là? unix.stackexchange.com/questions/4681/…  C'est presque une copie et vaut de l'or. Tu fais une normale dumais ajoutez le -h au sort commander. Vous pouvez ajouter -rh donc les plus gros sont les premiers dans le fichier, sinon vous avez besoin tail pour voir les porcs de l'espace. - SDsolar
Je ne m'attendais pas à ce qu'une telle question soit si populaire lorsque je l'ai cherché dans Google. - Mateen Ulhaq


Réponses:


À partir de GNU coreutils 7.5 sorti en août 2009, sort permet un -h paramètre qui autorise les suffixes numériques du type produit par du -h:

du -hs * | sort -h

Si vous utilisez un type qui ne prend pas en charge -h, vous pouvez installer GNU Coreutils. Par exemple. sur un ancien Mac OS X:

brew install coreutils
du -hs * | gsort -h

De sort Manuel:

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


1152
2017-07-01 12:29



La section pertinente du manuel: gnu.org/software/coreutils/manual/… - wodow
Facile à installer sur OS X avec homebrew - brasser, installez coreutils. - Richard Poirier
Bon un! Personnellement j'ai toujours fait du -BM | sort -nr En guise de solution de contournement, il est suffisamment lisible par l'homme et il est trié si quelqu'un est bloqué par des coreutils plus anciens. - chutz
Si vous utilisez OSX via Homebrew, notez que vous devez maintenant utiliser gsort plutôt que de trier: du -hs * | gsort -h - Brian Cline
@PaulDraper, du -BM affiche tout en mégaoctets, donc un fichier de 168 Ko s’affichera sous la forme 0M. À moins qu'il y ait un autre écart de version que je ne sache pas. Ma version de du affiche uniquement les valeurs en mégaoctets. - chutz


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

82
2018-02-25 13:52



Et cela fera une énorme quantité de doublons. - Douglas Leeder
D’abord, il fait la commande normale - puis, pour chaque entrée, il recalcule la taille afin de l’imprimer sous une forme lisible par l’homme. - Douglas Leeder
@ Douglas Leeder: vous avez raison pour le comptage des doublons, mais pensez que le second du ne commence pas à partir du cache froid (grâce à l'OS) @hasen j: xargs est une commande très utile, il divise son stdin et le nourrit sous forme d'arguments à la commande donnée - cadrian
Chris's est en réalité supérieur puisqu'il fonctionne avec des chemins contenant des espaces. Lancer un vote à votre façon, mon pote. - rbright
Moche, mais multi-plateforme :). - voretaq7


@ Douglas Leeder, encore une réponse: Triez la sortie lisible par l'homme de du -h à l'aide d'un autre outil. Comme 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)}<>;'

Divisé en deux lignes pour s'adapter à l'écran. Vous pouvez l'utiliser de cette façon ou en faire une ligne, cela fonctionnera dans les deux cas.

Sortie:

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

MODIFIER: Après quelques parties de golf, à PerlMonks, le résultat final est le suivant:

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

59
2018-02-25 21:04



Votre version courte sort sur stderr en raison de l die pouvez-vous le changer pour le rendre sortie sur stdout? - Dennis Williamson
Changer la die à un print et ça ira à stdout. C'est juste deux autres personnages. - Adam Bellaire
fonctionne sur Ubuntu! - marinara
hackistry perl impressionnant - nandoP
Le résultat est dans l'ordre inverse :( - RSFalcon7


J'utilise un outil extrêmement utile appelé ncdu conçu pour rechercher ces dossiers et fichiers à haute utilisation de disque et les supprimer. Il est basé sur la console, rapide et léger, et propose des packages pour toutes les distributions majeures.


50
2018-02-25 20:39



Très bien ... Je me demande si les résultats pourraient être alimentés à la norme ... Je suis tellement paresseux que je ne peux pas lire le manuel - ojblass
gt5 est dans la même veine; sa caractéristique tueur affiche la croissance. - Tobu
C'est vraiment cool! Et beaucoup plus vite que traîner avec du, si vous voulez juste identifier les grands annuaires. - BurninLeo


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

43
2018-02-25 14:01



juste ce que je cherchais merci - Edward Tanguay
Ne peut pas utiliser avec du -k --total, donne une erreur à la fin du: cannot access 'total': No such file or directory - laggingreflex
j'aime celui-ci plus toute autre réponse. comment iriez-vous pour ne montrer que les 50 premiers résultats? - Mauro
@Mauro - il suffit de diriger le résultat vers head en ajoutant `| tête -50` à la fin. - Samuel Lelièvre


Autant que je sache, vous avez trois options:

  1. Modifier du trier avant affichage.
  2. Modifier sort prendre en charge les tailles humaines pour le tri numérique.
  3. Post-traitement de la sortie de tri pour modifier la sortie de base en lisible par l'homme.

Tu pourrais aussi faire du -k et vivre avec des tailles en KiB.

Pour l'option 3, vous pouvez utiliser le script suivant:

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





J'ai eu ce problème aussi et j'utilise actuellement une solution de contournement:

du -scBM | sort -n

Cela ne produira pas de valeurs mises à l'échelle, mais produira toujours la taille en mégaoctets. C'est moins que parfait, mais pour moi c'est mieux que rien (ou afficher la taille en octets).


19
2018-02-25 13:56



J'aime le commutateur -BM, qui est fondamentalement le même que -m, mais il a l’avantage d’afficher la taille et le suffixe M, vous obtenez donc 10M, ce qui est beaucoup plus clair que 10! :) - Tom Feiner
C'est la solution la plus simple que j'ai vue jusqu'ici sur cette page, merci! - Jeff Olson


A trouvé cette publication autre part. Par conséquent, ce script shell fera ce que vous voulez sans appeler du sur tout deux fois. Il utilise awk convertir les octets bruts en un format lisible par l’homme. Bien entendu, le formatage est légèrement différent (tout est imprimé avec une précision d'une décimale).

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

Exécuter ceci dans mon .vim rendements de l'annuaire:

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

(J'espère que 3,6 millions de combinaisons de couleurs ne sont pas excessives.)


18
2018-02-25 14:09



J'ai aussi une réponse à Perl, mais je pense que cela pourrait amener les gens à me détester: du -B1 | trier -nr | perl -e '% h = (0 => b, 1 => K, 2 => M, 3 => G); pour (<>) {($ s, @ f) = scindé / \ 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
Même si la réponse Perl donne sa mise en forme beaucoup plus proche de du. Bien que l'arrondi soit désactivé ... On dirait que du donne toujours ceil () plutôt que round () - Adam Bellaire
Pourquoi ai-je utilisé un hash? Aurait dû être un tableau ... cerveau du matin plaindre.... - Adam Bellaire
Ajout d'une meilleure solution Perl comme autre réponse. - Adam Bellaire
Les deux versions échouent lorsque les noms de fichiers contiennent des espaces - Vi.