Aqui estão algumas abordagens:
com arredondamento
Como você parece perceber, printf
é uma ótima ferramenta para impressão formatada.
%f
é o formato para produzir um “número de ponto flutuante”,
ou seja, um número que não é um inteiro,
isto é, um número que inclui uma parte fracionária.
Como em todos os formatos printf,
um número (um inteiro!) imediatamente após o %
especifica o comprimento total da saída formatada,
possivelmente incluindo espaços.
Esse número pode ser seguido por um período ( .
) e outro número,
que especifica o número de posições decimais
(dígitos à direita do ponto decimal) para exibir.
Então, por exemplo, os comandos
printf "%12.2f\n" 1000000
printf "%12.2f\n" 1000
printf "%12.2f\n" 1
printf "%12.2f\n" 1.2345
printf "%12.2f\n" 1.6789
︙
produzirá a saída
1000000.00
1000.00
1.00
1.23
1.68
︙
Observe que 1.6789
foi arredondado para 1.68
.
Portanto, você deve conseguir o resultado desejado com este comando:
port rdeps mtr 2>/dev/null | sed -E "1 s/.*of (.*) @.*//" |
while IFS= read -r line
do
space="$(port space --units MiB --total $line 2>/dev/null | cut -d ' ' -f 1-2)"
space_num=${space% *}
space_mib=${space#* }
printf "%-20s%12.2f %s\n" "$line" "$space_num" "$space_mib"
done
O comando space=$(…)
é apenas a substituição do comando port space
que temos usado o tempo todo, mas com o resultado
(que se parece com 0.088 MiB
, por exemplo)
atribuído a uma variável temporária, space
.
Então space_num=${space% *}
define space_num
para a parte desse
antes do caractere de espaço (ou seja, o número; 0.088
neste exemplo),
e space_mib=${space#* }
conjuntos space_mib
para a parte
após o caractere de espaço (ou seja, as unidades, MiB
).
Finalmente colamos todas as partes juntas
usando printf
%12.2f
para exibir o número com duas casas decimais,
arredondando para o centésimo mais próximo,
e alinhando nos pontos decimais (como no exemplo anterior).
Para seus dados, isso parece
mtr 0.09 MiB
pkgconfig 0.62 MiB
libiconv 6.27 MiB
gperf 0.00 MiB
glib2 46.09 MiB
xz 1.68 MiB
gettext 24.83 MiB
expat 1.11 MiB
ncurses 15.17 MiB
libxml2 10.40 MiB
zlib 0.72 MiB
libffi 0.14 MiB
pcre 5.95 MiB
bzip2 0.65 MiB
libedit 0.80 MiB
Observe que 0.088 MiB
foi arredondado para 0.09 MiB
Note também que space_mib
é sempre definido como MiB
,
então, na verdade, não precisamos calculá-lo;
port rdeps mtr 2>/dev/null | sed -E "1 s/.*of (.*) @.*//" |
while IFS= read -r line
do
space_num="$(port space --units MiB --total $line 2>/dev/null | cut -d ' ' -f 1)"
printf "%-20s%12.2f %s\n" "$line" "$space_num" "MiB"
done
faz o mesmo que o anterior.
com truncamento
Para simplesmente truncar números, É melhor tratá-los como strings e não como números. Este comando
port rdeps mtr 2>/dev/null | sed -E "1 s/.*of (.*) @.*//" |
while IFS= read -r line
do
printf "%-30s%s\n" "$line" \
"$(port space --units MiB --total $line 2>/dev/null | cut -d ' ' -f 1-2)"
done | sed -E -e 's/(\..*) /0 /' -e 's/(.{25}) *(....\...).*( .*)//'
começa praticamente como a minha resposta anterior.
Mas então canaliza tudo através de um sed
, que tem duas partes:
-
s/(\..*) /0 /
Isso corresponde ao ponto decimal (\.
) e qualquer número de caracteres depois disso (.*
) até, mas não incluindo, um caractere de espaço. Em seguida, ele substitui toda a string de correspondência com a parte antes do espaço (), dois zeros e um espaço. (Eu poderia ter dito
s/(\..*)( )/0/
; faria a mesma coisa.) Isso altera0.088 MiB
para0.08800 MiB
e0.0 MiB
para0.000 MiB
. Se você tivesse42. MiB
em seus dados, isso mudaria para42.00 MiB
. Mas note que ele assume que cada número tem um ponto decimal, mesmo que não tenha nenhum dígito depois disso. (Também assume que não há períodos nas stringsmtr
,pkgconfig
,libiconv
, etc.)Precisamos fazer isso para garantir que são pelo menos dois dígitos após o ponto decimal em cada número; esse não é o caso de
gperf
até fazermos essa correção. -
s/(.{25}) *(....\...).*( .*)//
e.{25}
é a abreviação de.........................
; isto é, 25 caracteres arbitrários. Presumo que seja suficientemente longo para capturar o mais longo (por exemplo,libiconv
), mais profundamente recuado, string. Então qualquer número de caracteres (.*
), que, na verdade, espero ser apenas um monte de espaços. Então....\...
corresponde a quatro caracteres, um ponto decimal e mais dois personagens. Se você tiver um número de espaço maior que9999
, você terá que mudar isso para coincidir com mais de quatro dígitos à esquerda do ponto decimal. Então qualquer número de caracteres (.*
), que serão quaisquer dígitos após os dois primeiros após o ponto decimal. Então um espaço e o resto da linha (( .*)
), que eu espero que sejaMiB
. Em seguida, coloca as peças de volta como a corda (com os espaços principais e seguintes apropriados), o número (com espaços iniciais suficientes para tornar o.
o quinto caractere em) e, em seguida, as unidades.
A saída deste comando se parece com
mtr 0.08 MiB
pkgconfig 0.61 MiB
libiconv 6.27 MiB
gperf 0.00 MiB
glib2 46.09 MiB
xz 1.67 MiB
gettext 24.82 MiB
expat 1.10 MiB
ncurses 15.17 MiB
libxml2 10.40 MiB
zlib 0.72 MiB
libffi 0.14 MiB
pcre 5.95 MiB
bzip2 0.64 MiB
libedit 0.79 MiB
Observe que 0.088 MiB
foi truncado para 0.08 MiB
.
Claro que você pode colocar qualquer um dos comandos compostos acima em uma única linha
se você quiser, e você deve ajustar as constantes de largura
( 12
, 20
, 25
, 30
, etc.) para atender às suas necessidades.