Existe-t-il un outil standard qui convertit un nombre entier d'octets en un nombre lisible par l'homme de la plus grande taille d'unité possible, tout en conservant la valeur numérique entre 1,00 et 1023,99 ?
J'ai mon propre script bash/awk, mais je cherche un standard outil, qui se trouve sur de nombreuses/la plupart des distributions… quelque chose de plus généralement disponible, et a idéalement des arguments de ligne de commande simples, et/ou peut accepter une entrée canalisée.
Voici quelques exemples du type de sortie que je recherche.
1 Byt
173.00 KiB
46.57 MiB
1.84 GiB
29.23 GiB
265.72 GiB
1.63 TiB
Voici le bytes-human script (utilisé pour la sortie ci-dessus)
awk -v pfix="$1" -v sfix="$2" 'BEGIN {
split( "Byt KiB MiB GiB TiB PiB", unit )
uix = uct = length( unit )
for( i=1; i<=uct; i++ ) val[i] = (2**(10*(i-1)))-1
}{ if( int($1) == 0 ) uix = 1; else while( $1 < val[uix]+1 ) uix--
num = $1 / (val[uix]+1)
if( uix==1 ) n = "%5d "; else n = "%8.2f"
printf( "%s"n" %s%sn", pfix, num, unit[uix], sfix )
}'
Mettre à jour Voici une version modifiée de Gilles script, comme décrit dans un commentaire à sa réponse .. (modifié pour convenir à mon look préféré).
awk 'function human(x) {
s=" B KiB MiB GiB TiB EiB PiB YiB ZiB"
while (x>=1024 && length(s)>1)
{x/=1024; s=substr(s,5)}
s=substr(s,1,4)
xf=(s==" B ")?"%5d ":"%8.2f"
return sprintf( xf"%sn", x, s)
}
{gsub(/^[0-9]+/, human($1)); print}'
Réponse acceptée :
Non, il n'y a pas un tel outil standard.
Depuis GNU coreutils 8.21 (février 2013, donc pas encore présent dans toutes les distributions), sur Linux non embarqué et Cygwin, vous pouvez utiliser numfmt
. Il ne produit pas exactement le même format de sortie (à partir de coreutils 8.23, je ne pense pas que vous puissiez obtenir 2 chiffres après les décimales).
$ numfmt --to=iec-i --suffix=B --padding=7 1 177152 48832200 1975684956
1B
173KiB
47MiB
1.9GiB
De nombreux outils GNU plus anciens peuvent produire ce format et le tri GNU peut trier les nombres avec des unités depuis coreutils 7.5 (août 2009, donc présent sur les distributions Linux modernes non embarquées).
Je trouve votre code un peu compliqué. Voici une version plus propre d'awk (le format de sortie n'est pas exactement identique) :
awk '
function human(x) {
if (x<1000) {return x} else {x/=1024}
s="kMGTEPZY";
while (x>=1000 && length(s)>1)
{x/=1024; s=substr(s,2)}
return int(x+0.5) substr(s,1,1)
}
{sub(/^[0-9]+/, human($1)); print}'
(Republié à partir d'une question plus spécialisée)
En relation :Pourquoi personne n'utilise-t-il le véritable shell Bourne comme /bin/sh ?