出力は次のとおりです。
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
「要求された保護」行の末尾にある値です。私たちは最後から2番目の文字n
(この場合1)が欲しいです。 - ノード数は、
c
「ノード:」行の最後の値です。 - 個々の容量(TB単位)は、
m
「HDD合計」行の値です。 - 使用される容量は
p
「HDD Used」行の値でもあります。
この値に基づいて、次の計算を実行します。
- 合計 = m/c * (cy)TB
- 有効総容量 = m / c * (cy)*0.8TB
- 中古 = p/c TB
- 有効使用量 = p / c* (cy)*0.8TB
- 使用可能なボリューム = (m - p)/c * (cy)*0.8TB
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 は入力ファイルの 1 行を読み込み、条件ごとにテストします。条件は通常正規表現にすることができます。これは、正規表現が現在の行のどの位置にも一致する場合はtrueです。条件が true の場合は操作を実行します。
substr
length
期待して$n
解決する機能を実行することです。N現在の行の最初のフィールド(デフォルトでは、行は単に空のフィールドで区切られていますが構成可能です) NF
現在の行のフィールド数を含む変数であるため、$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" }'
あなたの例には、「要求された保護」出力にコロンで区切られた4つのフィールドが含まれていないため、スクリプトがこれを正確にどのように処理するかわかりませんが、説明に従っておよびをsubstr
使用して最後のフィールドの2番目の文字から逆数を取得しますですlength
。
あなたの例では、HDDフィールドT
にサフィックスが含まれていますが、Awkは抽出された数値に対して操作を実行するときにそのサフィックスを無視するため、そのまま残します。 (サフィックスがMでもGでもかまいません!)
インターネット検索では、isi storagepool
私に役立つ文書はまったく出てこなかった。 (しかし、このツールでマシンが読み取ることができる正しい出力を取得する方法はないようです。これは間違いなく最善の選択です。多くのツールにはXMLまたはJSON出力を生成するオプションがあるため、以下を行う必要はありません。デバイスを自動化したいツールごとに自分自身を解析します。
特に一致するものがないと、Nodes:
それでも失敗する可能性がありますが(ゼロ除算エラーが発生します)、全体的にこれはBashスクリプトよりもエレガントで読みやすく強力であることに同意します。 (もちろん、必要に応じて説明に単一の文字変数名を使用できますが、人間が読める変数名を使用する方が一般的にはメンテナンスが簡単です。)