【问题标题】:Convert number to gigabytes (sed, awk, sh, bash)将数字转换为千兆字节(sed、awk、sh、bash)
【发布时间】:2024-01-14 01:48:01
【问题描述】:

我有以下多行输出:

Volume Name: GATE02-SYSTEM
Size: 151934468096
Volume Name: GATE02-S
Size: 2000112582656

是否可以转换如下字符串:

Volume Name: GATE02-SYSTEM
Size: 141.5 Gb
Volume Name: GATE02-S
Size: 1862.75 Gb

使用 sed/awk?我为唯一的数字输出寻找答案,例如:

echo "151934468096" | awk '{ byte =$1 /1024/1024**2 ; print byte " GB" }'

但不知道如何将其应用于我的案例。

编辑:我想澄清一下我的情况。我有以下单行:

esxcfg-info | grep -A 17 "\\==+Vm FileSystem" | grep -B 15 "[I]s Accessible.*true" | grep -B 4 -A 11 "Head Extent.*ATA.*$" | sed -r 's/[.]{2,}/: /g;s/^ {12}//g;s/\|----//g' | egrep -i "([V]olume Name|^[S]ize:)"

生成上面的输出。我想知道在最后一个命令之后要添加什么以获得所需的输出。

【问题讨论】:

  • 为什么不将 1862.75 Gb 显示为 1.9 Tb ?看起来很明显
  • 我们有一堆
  • 我可以建议一个统一的解决方案,用于任何可以存在于任何相应单元10Kb100Mb123 Gb 等的任何数字......(根据其价值)跨度>

标签: linux bash awk sed sh


【解决方案1】:
printf "Volume Name: GATE02-SYSTEM\nSize: 151934468096\nVolume Name: GATE02-S\nSize: 2000112582656" |
awk '/^Size: / { $2 = $2/1024/1024**2 " Gb" }1'

【讨论】:

  • 嗯,可能 awk 在 ESXi 上受到某种限制。添加awk '/^Size: / { $2 = $2/1024/1024**2 " Gb" }' 生成零输出。
  • 抱歉,本来打算在最后的1 中编辑,但忘记了。现已更新。
  • 如果您最终还是通过管道连接到 Awk,那么您的整个管道可能应该重构为单个 Awk 脚本。如果无法访问该工具的原始输出,很难确切地说出如何做到这一点。 The documentation 暗示了一种脚本友好的“Perl”输出格式,但没有显示任何示例。如果您开始重构它,可能会使用它。
  • 我可以在从远程主机上接受命令后重新格式化字符串,使用完全实现的 awk 和 sed。只是想把它作为单行来做,但是 awk 和 sed 在 ESXi 上是有限的。
  • 在 ESXi 上 awk 以什么方式受到限制?
【解决方案2】:

使用 (GNU) sedbc

... | sed 's@Size: \([0-9]*\)@printf "Size: %s" $(echo "scale = 2; \1 / 1024 ^ 3" | bc)GiB@e'
             ^^^^  ^^^^^^^^^^ ^^^^^^                    ^^^^^^^^^  ^^ ^^^^^^^^^^    ^^     ^
               1        2        3                          4       5      6         7     8
  1. 匹配Size: 行。
  2. 捕获字节数(如果为空或为零,则可能易受攻击,加强生产使用)
  3. 替换为printf 输出
  4. scale = 设置 bc 的小数位数
  5. 使用sed 捕获组(字节数)
  6. 字节数的数学运算
  7. 将所有内容发送至bc 进行评估
  8. 告诉sed 在子shell 中执行s 语句的“替换”部分。

Another optionnumfmt(如果可用,自 GNU coreutils 8.21 起):

... | sed 's@Size: \([0-9]*\)@printf "%s" $(echo \1 | numfmt --to=iec-i --suffix=B)@e'

这不能让您控制小数,但对所有大小都“有效”(即在数字足够大的情况下给出 TiB,对于太小的数字不会截断为“0.00 GiB”)。

【讨论】:

  • 向@fedorqui 大声疾呼this answer 如何将sed 捕获组替换为对该组运行的shell 命令的输出。