Existe uma ferramenta padrão que converte uma contagem inteira de bytes em uma contagem legível por humanos do maior tamanho de unidade possível, mantendo o valor numérico entre 1,00 e 1023,99?
Eu tenho meu próprio script bash / awk, mas estou procurando uma ferramenta padrão , encontrada em muitas / muitas distros ... algo mais geralmente disponível e, idealmente, possui argumentos de linha de comando simples e / ou pode aceitar entrada canalizada.
Aqui estão alguns exemplos do tipo de saída que estou procurando.
1 Byt
173.00 KiB
46.57 MiB
1.84 GiB
29.23 GiB
265.72 GiB
1.63 TiB
Aqui está o script bytes-human (usado para a saída acima)
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%s\n", pfix, num, unit[uix], sfix )
}'
Atualizar Aqui está uma versão modificada do script de Gilles , conforme descrito em um comentário à resposta dele (modificado para se adequar à minha aparência preferida).
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"%s\n", x, s)
}
{gsub(/^[0-9]+/, human($1)); print}'
fonte
standard tool
na tomada :)Respostas:
Não, não existe essa ferramenta padrão.
Desde o GNU coreutils 8.21 (fevereiro de 2013, ainda não presente em todas as distribuições), no Linux e Cygwin não incorporado, você pode usar
numfmt
. Ele não produz exatamente o mesmo formato de saída (a partir do coreutils 8.23, acho que você não pode obter 2 dígitos após os pontos decimais).Muitas ferramentas GNU mais antigas podem produzir esse formato e a classificação GNU pode classificar números com unidades desde o coreutils 7.5 (agosto de 2009, tão presente nas modernas distribuições Linux não incorporadas).
Acho seu código um pouco complicado. Aqui está uma versão mais limpa do awk (o formato de saída não é exatamente idêntico):
( Enviado a partir de uma pergunta mais especializada )
fonte
s
deveria estar liderandoB
. Além disso, essa string é facilmente alterada para notação binária IEC. (2) Ignora o intervalo 1000-1023 em favor de 1 <próximo tamanho> (facilmente alterado) (3) Não possui valores decimais (o que eu quero). Novamente, isso é facilmente alterado. Ao exibir duas casas decimais, o%f
formato causa around-up
para o <próximo tamanho> para os valores 1019-1023 ; mas não vale a pena uma solução alternativa. Publiquei uma versão modificada na minha resposta, para referência geral.du
números em formato legível por humanos, observe que pode ser necessário adicionar--block-size=1
aodu
comando.A partir da versão v.
8.21
,coreutils
Incluinumfmt
:por exemplo
Vários outros exemplos (incluindo filtragem, processamento de entrada / saída etc.) são apresentados AQUI .
Além disso, a partir de
coreutils
v.8.24
,numfmt
Pode processar vários campos com especificações faixa de campo semelhantescut
, e suporta definir a precisão de saída com a--format
opçãopor exemplo,
fonte
Aqui está uma opção apenas para o bash, nenhum
bc
ou qualquer outro não embutido, + formato decimal e unidades binárias.Exemplos:
Deve ter bom desempenho em qualquer versão do Bash existente (incluindo o BYS para Windows do MSYSGit).
fonte
Esta é uma reescrita completa inspirada na versão modificada de Peter.O do script awk de Gilles.
Alterar:
Código:
Casos de teste (se você quiser ver a saída):
Desfrutar!
fonte
Existem alguns
perl
módulos no CPAN: Format :: Human :: Bytes e Number :: Bytes :: Human , sendo o último um pouco mais completo:E o contrário:
NOTA: a função
parse_bytes()
foi adicionada na versão 0.09 (01/03/2013)fonte
Via linux - Existe uma calculadora de linha de comando para cálculos de bytes? - Stack Overflow , eu descobri sobre as unidades GNU - embora sem exemplos na página SO; e como eu não o vi listado aqui, aqui está uma pequena nota sobre isso.
Primeiro, verifique se as unidades estão presentes:
Dado que são, faça uma conversão -
printf
especificadores de formato são aceitos para formatar o resultado numérico:fonte
Na verdade, existe um utilitário que faz exatamente isso. Eu sei porque fui eu quem o escreveu. Foi escrito para * BSD, mas você deve compilar no Linux se você tiver as bibliotecas BSD (que eu acredito que sejam comuns).
Acabei de lançar uma nova versão, postada aqui:
http://blog.frankleonhardt.com/2015/freebsd-hr-utility-human-readable-number-filter-man-page/
Chama-se hr e leva stdin (ou arquivos) e converte números para o formato legível por humanos de uma maneira que (agora) é exatamente igual a ls -h e assim por diante, e pode selecionar feeds individuais em linhas, escala unidades pré-dimensionadas (por exemplo, se estiverem em blocos de 512 bytes, convertê-las em Mb, etc.), ajuste o preenchimento das colunas e assim por diante.
Escrevi alguns anos atrás, porque achava que tentar escrever um shell script, embora intelectualmente interessante, também fosse uma loucura total.
Usando hr, por exemplo, você pode facilmente obter uma lista ordenada de tamanhos de diretório (que saem em unidades de 1 KB e precisam ser alteradas antes da conversão) com o seguinte:
du -d1 | classificar -n | hr -sK
Enquanto du produzirá a saída -h, a classificação não será classificada por ela. A adição de -h aos utilitários existentes é um caso clássico de não seguir a filosofia do unix: ter utilitários simples realizando tarefas definidas muito bem.
fonte
Aqui está uma maneira de fazê-lo quase puramente no bash, só precisa de 'bc' para a matemática de ponto flutuante.
Uso:
Resultado:
fonte
Dá:
Infelizmente, não consigo descobrir como obter precisão de duas casas decimais. Testado no Ubuntu 14.04.
fonte
A primeira resposta de @ don_crissti é boa, mas pode ser ainda mais curta usando Here Strings , por exemplo
ou mesmo
se
<<<
não estiver disponível, você pode usar, por exemplo,fonte
Existem ferramentas Python
Eu não vejo uma flag --binary :(, então você teria que usar python diretamente para representação binária:
fonte
Eu tive o mesmo problema e rapidamente criei uma solução simples usando
awk
alog()
função:E a precisão perdida no uso de números flutuantes não é tão ruim, pois essa precisão será perdida de qualquer maneira.
fonte
A resposta para sua pergunta é sim.
Embora o formato de saída não corresponda exatamente às suas especificações, a conversão em si é facilmente realizada por uma ferramenta muito padrão (ou duas) . Os que eu me refiro são
dc
ebc
. Você pode obter um relatório segmentado alterando as radias de saída. Como isso:... que imprime ...
Eu uso
dc
acima porque é um favorito pessoal, masbc
pode fazer o mesmo com sintaxe diferente e adere às mesmas regras de formato especificadas pelo POSIX, como:bc
obasebc
deve escrever números decimais de dois dígitos; para bases de 101 a 1000, cadeias decimais de três dígitos e assim por diante. Por exemplo, o número decimal 1024 na base 25 seria escrito como:01 15 24
e na base 125, como:
008 024
fonte
Solução curta e doce, apenas com casca:
Não mostra a poção decimal.
O
let VAR=expression
é Korn-ish. SubstituaVAR=$(( expression ))
por Born-again-ish.fonte
AFAIK não existe uma ferramenta padrão para a qual você pode passar texto e ele retorna um formulário legível por humanos. Você pode encontrar um pacote para realizar a tarefa mencionada para sua distribuição.
No entanto, não entendo por que você pode precisar dessa ferramenta. A maioria dos pacotes que fornecem uma saída relacionada geralmente possui uma opção -h ou equivalente para saída legível por humanos.
fonte