ストレージディスクへの次の入力を次の形式の出力に置き換えたいと思います。以下のスクリプトはほぼ効果的でした。しかし、これはT0では機能しません。 "replaceTier"関数で数字の終わりのゼロを正しく読み取るのに問題があるようです。
校正をお手伝いできますか?よろしくお願いします。
**INPUT IN FILE:**
displayName=00:19:78
sizeInKB=26214720
dpPoolID=1
displayName=00:FE:B0
sizeInKB=2251536384
dpPoolID=110
displayName=00:FE:B1
sizeInKB=2251536384
dpPoolID=110
**EXPECTED OUTPUT:**
1978,T1
FEB0,T0
FEB1,T0
replaceTier=(
{1,11,12,13,14,15,16,17,18,19,51,61,71,81,100}:T1
{2,21,22,23,24}:T2
3:T3
{10,110}:T0
90:SVC_T1
91:SVC_T2
92:SVC_T1
)
#
while read -r name serial model uid
do
cat "$DIR"/"$name"_disks.log | grep -v 'sizeInKB' | cut -d "=" -f2 | sed 's/\://g' | xargs -n2 | sed 's/\ /\,/g' | cut -c 3- | grep -v ',-1' > "$DIR"/"$name"_output.log
for row in "${replaceTier[@]}"; do
original="$(echo $row | cut -d: -f1)";
new="$(echo $row | cut -d: -f2)";
sed -i -e "s/,${original}.*/,${new}/g" "$DIR"/"$name"_output.log;
done
done < /storage/logs/HDSlist.txt
答え1
ありがとうございます。あなたは正しいです。 '.*' は '$' に置き換える必要があります。今はうまくいきます。返品そこ私にも必ず必要な情報を見つけた。
sed -i -e "s/,${original}$/,${new}/g" "$DIR"/"$name"_output.log;
あなたの努力に感謝します。
答え2
問題は正規表現の終わりにあるワイルドカードです。
s/,${original}.*/,${new}/g
.*
110 はテーブルの最初の 11 または 1 と一致するため、replaceTier
110 は T0 ではなく T1 (1:T1 マッピングで) に変換されます。
代わりに、翻訳したい数字と正確に一致するものが必要なので、正確な数字のみを一致させるようにアンカー(行末と一致)を削除して.*
追加してください。$
s/,${original}\$/,${new}/g
ところで、ログファイルの解析が複雑すぎるようです。スクリプトを使用すると仮定すると、bash
次のようになります。
while read -r displayName; do
# Read two more rows of data from the
# input file.
read -r sizeInKB # ignored
read -r dpPoolID
# Process displayName, remove everything
# up to the first ":", then drop the
# remaining ":" in the middle.
displayName=${displayName#*:}
displayName=${displayName/:/}
# Look up dpPoolID in replaceTier.
tier=""
for row in "${replaceTier[@]}"; do
# Split row into id:tier.
id=${row%%:*}
if [[ "$dpPoolID" = "$id" ]]; then
tier=${row#*:}
break
fi
done
if [[ -n "$tier" ]]; then
# Only print when tier was found, so skip
# invalid dpPoolIDs such as -1, etc.
printf "%s,%s\n" "$displayName" "$tier"
fi
done <"$DIR"/"$name"_disks.log >"$DIR"/"$name"_output.log
これは、同じファイルへの複数の読み取りと書き込みを防ぐだけでなく、組み込みbash
関数(no 、、、、grep
)のみを使用するため、外部プロセスの作成に伴う多くのオーバーヘッドがなくなりました。sed
cut
xargs
ただし、この場合でも連想配列を使用すると改善の余地がありますreplaceTier
。この場合、各行で完全に繰り返すのではなく、直接クエリを実行できます。
以下を使用して、これらの連想配列を定義できます。
replaceTier=(
[1]=T1
[12]=T1
[13]=T1
[14]=T1
...
[100]=T1
[2]=T2
[21]=T2
...
[24]=T2
[3]=T3
[10]=T0
[110]=T0
[90]=SVC_T1
[91]=SVC_T2
[92]=SVC_T1
)
この場合、最も内側のfor
ループを直接照会に簡素化できます。
tier=${replaceTier[$id]}
これは、特にテーブルサイズが大きくreplaceTier
なるほど効率的です。