awk 匹配模式并将数字转换为不同的单位

awk match pattern and convert number to different unit

我有一个包含此类值的 csv 文件:

vm47,8,32794384Ki,16257320Ki
vm47,8,30223304245,15223080Ki
vm48,8,32794384Ki,16257312Ki
vm48,8,30223304245,15223072Ki
vm49,8,32794384Ki,16257320Ki
vm49,8,30223304245,15223080Ki

第 3 列和第 4 列是以字节或千字节表示的内存值。问题是“Ki”字符串在CSV文件中随机出现,尤其是第3列,不一致。

所以为了使文件一致,我需要将所有内容转换为字节。所以基本上,任何匹配尾随“Ki”的值都需要将其数值乘以 1024,然后替换相应的 XXXXXKi 匹配项。

我想用 awk 来做的原因是因为我已经在使用 awk 来生成那个 csv 格式,但我也很乐意用 sed 来做。

到目前为止,这是我的代码,但显然它是错误的,因为它将第 3 列和第 4 列中的任何值乘以 1024,即使它与“Ki”不匹配。我现在不确定如何询问 awk“如果你在末尾看到 Ki,则乘以 1024”。

kubectl describe node --context=$context| sed -E '/Name:|cpu:|ephemeral-storage:|memory:/!d' | sed 's/\s//g' | awk '
BEGIN {FS = ":"; OFS = ","}
{record[] = }
 == "memory" {print record["Name"], record["cpu"], record["ephemeral-storage"], record["memory"]}
' | awk -F, '{print ,,,*1024,,*1024}' >> describe_nodes.csv

编辑:我弄错了,您需要乘以 128 才能将 KiB 转换为字节,而不是 1024。

"if you see Ki at the end, then multiply by 1024

您可以使用:

awk 'BEGIN{FS=OFS=","}  ~ /Ki$/ { *= 1024}  ~ /Ki$/ { *= 1024} 1' file

vm47,8,33581449216,16647495680
vm47,8,30223304245,15588433920
vm48,8,33581449216,16647487488
vm48,8,30223304245,15588425728
vm49,8,33581449216,16647495680
vm49,8,30223304245,15588433920

或者更短一点:

awk 'BEGIN{FS=OFS=","} {
for (i=3; i<=4; ++i) $i ~ /Ki$/ && $i *= 1024} 1' file

根据您显示的 samples/attempts,请尝试以下 awk 代码。简单的解释是,从第 3 个字段开始遍历字段并查找值是否具有 Ki(忽略大小写方式)然后将其乘以 128,最后打印所有 edited/non-edited 行。

awk 'BEGIN{FS=OFS=","} {for(i=3;i<=NF;i++){if($i~/[Kk][Ii]$/){$i *= 128}}} 1' Input_file

你可以试试 numfmt:

$ numfmt -d, --field 3,4 --from=auto --to=none <<EOF
vm47,8,32794384Ki,16257320Ki
vm47,8,30223304245,15223080Ki
EOF
vm47,8,33581449216,16647495680
vm47,8,30223304245,15588433920