web-dev-qa-db-fra.com

Comment trier la taille lisible par l'homme

Je recherche essentiellement des fichiers, puis je trie par taille. Le script fonctionne si je ne trie pas la taille par lisible par l'homme. Mais je veux que la taille soit lisible par l'homme. Comment trier des tailles lisibles par l'homme?

Par exemple:

 ls -l | sort -k 5 -n | awk '{print $9 " " $5}'

Cela fonctionne comme prévu, j'ai la taille de mes fichiers en octets croissante:

1.txt 1
test.txt 3
bash.sh* 573
DocGeneration.txt 1131
andres_stuff.txt 1465
Branches.xlsx 15087
foo 23735
bar 60566
2016_stuff.pdf 996850

Maintenant, je veux que la taille soit lisible par l'homme, j'ai donc ajouté un paramètre -h à ls, et maintenant certains fichiers sont hors service:

 ls -lh | sort -k 5 -n | awk '{print $9 " " $5}'
1.txt 1
DocGeneration.txt 1.2K
andres_stuff.txt 1.5K
test.txt 3
Branches.xlsx 15K
foo 24K
bar 60K
bash.sh* 573
2016_stuff.pdf 974K

11
tvo000

Essayez sort -h k2

-h, --human-numeric-sort compare les nombres lisibles par l'homme (par exemple, 2K 1G)

Cela fait partie du tri gnu, du tri BSD et d'autres.

28
ctrl-alt-delor

ls a cette fonctionnalité intégrée, utilisez le -S option et tri dans l'ordre inverse: ls -lShr

       -r, --reverse
              reverse order while sorting

       -S     sort by file size, largest first
29
Mark McKinstry

Puisqu'aucun shell spécifique n'a été mentionné, voici comment faire le tout dans le shell zsh:

ls -lhf **/*(.Lk-1024oL)

Le modèle global ** Correspond comme * Mais à travers / Dans les noms de chemin, c'est-à-dire comme le ferait une recherche récursive.

La commande ls activerait les tailles lisibles par l'homme avec -h Et le format de sortie de longue liste avec -l. L'option -f Désactive le tri, donc ls listerait simplement les fichiers dans l'ordre où ils sont donnés.

Cet ordre est organisé par le modèle de globalisation de nom de fichier **/*(.Lk-1024oL) afin que les fichiers plus petits soient répertoriés en premier. Le bit **/* Correspond à tous les fichiers et répertoires de ce répertoire et ci-dessous, mais le (...) Modifie le comportement du glob (c'est un "qualificatif glob").

C'est le oL à la fin qui ordonne (o) les noms par taille de fichier (L, "longueur").

Le . Au début fait que le glob ne correspond qu'aux fichiers normaux (pas de répertoires).

Le bit Lk-1024 Sélectionne les fichiers dont la taille est inférieure à 1024 Ko ("longueur en Ko inférieure à 1024").

Si zsh n'est pas votre shell interactif principal, vous pouvez utiliser

zsh -c 'ls -lf **/*(.Lk-1024oL)'

Utilisez setopt GLOB_DOTS (Ou zsh -o GLOB_DOTS -c ...) Pour faire correspondre les noms cachés. ... ou ajoutez simplement D à la chaîne de qualificatif glob.


En développant ce qui précède, en supposant que vous souhaitiez une sortie à 2 colonnes avec des noms de chemin et des tailles lisibles par l'homme, et en supposant également que vous avez numfmt from GNU coreutils,

zmodload -F zsh/stat b:zstat

for pathname in **/*(.Lk-1024oL); do
    printf '%s\t%s\n' "$pathname" "$(zstat +size "$pathname" | numfmt --to=iec)"
done

ou, plus vite,

paste <( printf '%s\n' **/*(.Lk-1024oL) ) \
      <( zstat -N +size **/*(.Lk-1024oL) | numfmt --to=iec )
5
Kusalananda

Si votre sort n'a pas le -h option, vous pouvez utiliser une commande awk (quoique très longue) comme celle-ci:

find . -type f -size -1024k -exec ls -al {} \; | sort -k 5 -n | awk '{if ($5 > 1099511627776) {print $9,$5/1024/1024/1024/1024"T"} else if ($5 > 1073741824) {print $9,$5/1024/1024/1024"G"} else if ($5 > 1048576) {print $9,$5/1024/1024"M"} else if ($5 > 1024) {print $9,$5/1024"K"} else {print $9,$5"B"}}' | column -t

Cela triera votre sortie en octets puis les convertira à leur taille lisible par la suite.

4
jesse_b