输出如下所示:
Name: s210_21tb_800gb-ssd_128gb
Nodes: 1, 2, 3
Requested Protection: +2d:1n
HDD Used: 13.2094T
HDD Total: 55.9520T
HDD % Used: 23.61%
从该输出中,提取以下信息。
- 奇偶校验
y
是“请求的保护”行末尾的值。我们想要倒数第二个字符n
(在本例中为 1)之前 - 节点数
c
是“Nodes:”行中的最后一个值 - 单个容量(以 TB 为单位)
m
是“HDD Total”行中的值 - 已用容量
p
同样是“HDD 已用”行中的值
根据这些值,我们执行以下计算。
- 总计 = m /c * (cy) TB
- 有效总容量 = m / c * (cy)*0.8 TB
- 已用 = p / c TB
- 有效使用 = p / c* (cy)*0.8 TB
- 可用卷 = (m - p)/c * (cy)*0.8 TB
是否可以使用 python 脚本在表中获得以下输出?
这是我们当前的脚本:
#!/bin/bash
y=$(grep -n Protection storage_info | cut -d ':' -f4 | cut -c1)
echo y=$y
c=$(grep -n Node storage_info | awk '{print substr($0,length,1)}')
echo c=$c
m=$(grep "HDD Total" storage_info | cut -d ':' -f2|rev|cut -c 2- | rev)
echo m=$m
p=$(grep "HDD Used" storage_info_info | cut -d ':' -f2|rev|cut -c 2- | rev)
echo p=$p
echo parity=$y
echo Nodenumber=$c
div=$(echo $m/$c| bc)
div1=$(echo $p/$c| bc)
minus=$(echo $c-$y|bc)
minus1=$(echo $m-$p|bc)
Total=$(echo $div \* $minus |bc)
echo "Total = $Total TB"
EffectiveTotalvolume=$(echo $div \* $minus \* 0.8 |bc)
echo "Effective Total volume = $EffectiveTotalvolume TB"
echo "USED =$div1 TB"
Effectiveused=$(echo $div1 \* $minus \* 0.8 |bc)
echo "Effective used=$Effectiveused TB"
Availablevolume=$(echo $minus1/$c \* $minus \* 0.8|bc)
echo "Available volume=$Availablevolume TB"
这是所需的输出:
Total = 36 TB
Effective Total volume = 28.8 TB
USED =4 TB
Effective used=6.4 TB
Available volume=22.4 TB
(这些值与示例输出不对应,它们是不同的运行,抱歉。)
答案1
事实上,Python 具有通用且详细的打印格式化工具。一个很好的概述可以在https://pyformat.info/以及代码示例等
不过,我猜你的真实的这里的问题是“我怎样才能修复这个脚本,使其不那么脆弱”。我的建议是使用 Awk。
Awk 脚本的一般语法是一系列条件{
动作}
块。 awk 读取输入文件的一行并根据每个条件对其进行测试。条件通常可以是正则表达式,如果正则表达式与当前行中的任何位置匹配,则该条件为 true。如果条件为真,则执行操作。
substr
和length
是执行您期望的功能并$n
解决n当前行的第一个字段(默认情况下,该行简单地分为空白字段,尽管这也是可配置的)。 NF
是一个变量,包含当前行上的字段数; so$NF
指当前行的最后一个字段。
最后,END
当输入文件全部被读取时执行该条件。 (BEGIN
在读取任何输入之前,您还可以使用一个条件来执行操作。)
isi storagepool list -v |
awk '# Assume parity is second to last character on this line?
/Requested Protection:/ { parity=substr($NF,length($NF)-1,1) }
/Nodes:/ { nodes=$NF }
/HDD Total/ { hdd_total=$NF } # Awk helpfully ignores T suffix
/HDD Used/ { hdd_used=$NF } # here too
END {
multiplier=nodes-parity
total=hdd_total/nodes*multiplier
used=hdd_used/nodes
print "Total = " total " TB"
print "Effective Total volume = " total*0.8 " TB"
print "USED =" used " TB" # no space after =, really?
print "Effective used=" used*multiplier*0.8 " TB" # double ditto
print "Available volume=" (hdd_total-hdd_used)/nodes*multiplier*0.8 " TB" }'
您的示例在“请求的保护”输出中都不包含四个以冒号分隔的字段,因此不清楚您的脚本如何准确处理该字段;但根据您的描述,我们使用substr
和从最后一个字段中获取倒数第二个字符length
。
HDD 字段T
在您的示例中包含后缀,但在对提取的数字进行算术时,Awk 会忽略该后缀,因此我们只需将其保留。(如果后缀也可以是 M 或 G,那将是一个问题!)
谷歌搜索并isi storagepool
没有真正为我产生任何有用的文档。 (但似乎确实没有办法从此工具获得正确的机器可读输出,这绝对是最好的选择。许多工具都可以选择生成 XML 或 JSON 输出,因此您不必自己动手您想要自动化的每个工具的解析器。)
如果没有特别匹配的内容,这仍然可能会失败Nodes:
(然后你会得到除以零的错误),但总的来说,我认为你会同意这比你的 Bash 脚本更优雅、更易读、更健壮、更高效。 (当然,如果您愿意,您可以使用说明中的单字符变量名称;但是具有人类可读的变量名称通常更易于维护。)