
sedを使用してTBをGBに変換しようとしています。 TBのあるフィールドは、1桁の数字(2T、8T)または複数桁の数字(2.001T、1.501T)です。交換品が正常に動作していると思っていましたが、エラーが発生して理解できないようです。
ファイルサンプル:
ftwepsiprdsql02,ftwepsiprdsql02_F,2.001T,1.680T
ftwepsiprdsql02,ftwepsiprdsql02_G,801G,176.786G
ftwepsiprdsql02,ftwepsiprdsql02_H,501G,6.565G
ftwepsiprdsql02,ftwepsiprdsql02_I,1.001T,539.504G
ftwepsiprdsql02,ftwepsiprdsql02_J,501G,478.211G
ftwepsiprdsql02,ftwepsiprdsql02_X,1.501T,68.021G
rxi0738_foc_cl1,rxi0738_foc_cl1_lun248,8T,4.450T
rxi0738_foc_cl1,rxi0738_foc_cl1_lun250,8T,5.857T
rxi0738_foc_cl1,rxi0738_foc_cl1_lun252,8T,4.681T
rxi0738_foc_cl1,rxi0738_foc_cl1_lun254,8T,4.657T
3番目と4番目のフィールド(割り当て/使用容量)をそれぞれ変更します。最初のアプローチは、1桁の容量の数字を複数桁の数字(2.000T、8.000T)と一致するように変更することでした。
3番目のフィールドの1桁のコードを置き換えます。
for i in `awk -F , '{print $3}' $TMPRPT| grep \[0-9\]T | grep -v "\." `
do
TVAL=$(echo $i | sed 's/T/.000T/')
sed -i .tmp "s/$i/$TVAL/" "$TMPRPT"
done
理論的には、すべての1桁の数字を複数桁の数字に合わせて変更する必要があるため、TBからGBへの最終変換は簡単です。 awkコマンドは完全に実行され、私にただ1桁の出力ですが、一度forループに入れてsed -iコマンドを実行すると、置き換えが行われます。みんな複数桁の数字を含むT名のフィールド:
ftwepsiprdsql02,ftwepsiprdsql02_F,2.001.000T,1.680T
ftwepsiprdsql02,ftwepsiprdsql02_G,801G,176.786G
ftwepsiprdsql02,ftwepsiprdsql02_H,501G,6.565G
ftwepsiprdsql02,ftwepsiprdsql02_I,1.001.000T,539.246G
ftwepsiprdsql02,ftwepsiprdsql02_J,501G,478.211G
ftwepsiprdsql02,ftwepsiprdsql02_X,1.501.000T,68.021G
rxi0738_foc_cl1,rxi0738_foc_cl1_lun248,8.000T,4.450T
rxi0738_foc_cl1,rxi0738_foc_cl1_lun250,8.000T,5.857T
rxi0738_foc_cl1,rxi0738_foc_cl1_lun252,8.000T,4.681.000T
rxi0738_foc_cl1,rxi0738_foc_cl1_lun254,8.000T,4.657T
これを行うより簡単な方法があることを知っているので、他の選択肢も開いていますが、sed -iが好きな方法で動作するようにする方法も知りたいです。
(プラットフォームはLinuxカーネルの縮小版を実行するIsilonです。ほとんどのコマンドを使用できますが、すべてではありません。)
答え1
GNU Coreutilsがある場合numfmt
:
$ numfmt -d, --field=3,4 --from=auto --round=nearest < file |
numfmt -d, --field=3,4 --to-unit=G --suffix=G
ftwepsiprdsql02,ftwepsiprdsql02_F,2001G,1680G
ftwepsiprdsql02,ftwepsiprdsql02_G,801G,177G
ftwepsiprdsql02,ftwepsiprdsql02_H,501G,7G
ftwepsiprdsql02,ftwepsiprdsql02_I,1001G,540G
ftwepsiprdsql02,ftwepsiprdsql02_J,501G,479G
ftwepsiprdsql02,ftwepsiprdsql02_X,1501G,69G
rxi0738_foc_cl1,rxi0738_foc_cl1_lun248,8000G,4450G
rxi0738_foc_cl1,rxi0738_foc_cl1_lun250,8000G,5857G
rxi0738_foc_cl1,rxi0738_foc_cl1_lun252,8000G,4681G
rxi0738_foc_cl1,rxi0738_foc_cl1_lun254,8000G,4657G
またはPerlを使用して:
perl -F, -pe '
$_ = join ",", map { $_ =~ s/^(\d*(\.\d+)?)T$/sprintf "%.0fG", 1000*$1/e; $_ } @F
' file
答え2
1T=1000G と仮定します。
sedが完了したので、理論的には乗算に必要なものよりも強力ですが、短く保ち、ループを使用せずに単純なテキスト置換で変更しました。
必要な変更を分析しましょう。 Tがあるがピリオドはない単一のフィールドを「.000」のフィールドに変更することから始めます。フィールドが2つなので、「g」が必要です。フィールドを開始するための良いカンマがあるので、それを活用してください。
s/\(,[0-9]*\)T/\1.000T/g
小数点以下の3桁のフィールドがない場合に備えて、クリーンアップを実行します。ピリオドの後に何もない場合は3つのゼロを追加し、1つの数字がある場合は2つの0を追加し、2つの数字がある場合は0を追加し、3番目の数字の後にある余分な数字を削除します。
s/\(,[0-9]*\.\)T/\1000T/g
s/\(,[0-9]*\.[0-9]\)T/\100T/g
s/\(,[0-9]*\.[0-9][0-9]\)T/\10T/g
s/\(,[0-9]*\.[0-9][0-9][0-9]\)[0-9]*T/\1T/g
次に、TをGに変更し、ピリオドを削除します。
s/\(,[0-9]*\)\.\([0-9][0-9][0-9]\)T/\1\2G/g
ここで、便宜のために前のゼロを削除してください。
s/,0*\([1-9][0-9]*G\)/,\1/g
すべてのコマンドをまとめてサンプルデータ結果を提供
ftwepsiprdsql02,ftwepsiprdsql02_F,2001G,1680G
ftwepsiprdsql02,ftwepsiprdsql02_G,801G,176.786G
ftwepsiprdsql02,ftwepsiprdsql02_H,501G,6.565G
ftwepsiprdsql02,ftwepsiprdsql02_I,1001G,539.504G
ftwepsiprdsql02,ftwepsiprdsql02_J,501G,478.211G
ftwepsiprdsql02,ftwepsiprdsql02_X,1501G,68.021G
rxi0738_foc_cl1,rxi0738_foc_cl1_lun248,8000G,4450G
rxi0738_foc_cl1,rxi0738_foc_cl1_lun250,8000G,5857G
rxi0738_foc_cl1,rxi0738_foc_cl1_lun252,8000G,4681G
rxi0738_foc_cl1,rxi0738_foc_cl1_lun254,8000G,4657G