![awk、パラメータセットを使用してファイルの値を変更するにはどうすればいいですか?](https://rvso.com/image/50660/awk%E3%80%81%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%82%BB%E3%83%83%E3%83%88%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E5%80%A4%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF%E3%81%A9%E3%81%86%E3%81%99%E3%82%8C%E3%81%B0%E3%81%84%E3%81%84%E3%81%A7%E3%81%99%E3%81%8B%3F.png)
を使用してデータをリセットしようとしていますawk
。54 列のデータがあり、次のスクリプトを使用して 6 つの列の値を変更したいと考えています。
#!/bin/bash -x
# optimal parameters
set BI2=0.02841513
set DS2=0.37837487
set WS2=0.85392380
set D22=1.00048351
set D32=0.63893676
set DSMAX2=28.15795517
# change the calibration parameter
awk '{if($1==2) {
$6 = "${BI2}"
$7 = "${DS2}"
$8 = "${DSMAX2}"
$9 = "${WS2}"
$25 = "${D22}"
$26 = "${D32}"}
print $0;}' soil_params > tmp
mv -f tmp soil_params
私のデータは次のようになります:
999 0 123 65.183534 -147.655522 0.2 0.001 10 0.9 2 10.84 9.79 9.76 812.42 1546.28 1334.35 -999 -999 -999 18.579 68.139 26.914 548 0.1 0.3 0.192752 -0.8725 4 35.39 30.13 19.34 0.323 0.347 0.382 1160.4 1196.2 1208.9 2186.08 2253.52 2411.44 -9.8 0.582 0.489 0.443 0.396 0.4841 0.28 0.001 0.0005 383.7 0.1 0.1 0.1 1 16.733299 16.733299
2 1 124 65.183534 -147.639897 ${BI2} ${DS2} ${DSMAX2} ${WS2} 2 10.84 9.79 9.77 812.51 1544.96 1331.78 -999 -999 -999 18.579 68.277 26.915 676 0.1 ${D22} ${D32} -0.529166 4 35.45 30.19 19.37 0.323 0.347 0.382 1160.3 1196.3 1208.8 2185.87 2253.63 2411.11 -9.8 0.582 0.49 0.443 0.396 0.4851 0.28 0.001 0.0005 400.8 0.1 0.1 0.1 1 16.32 16.32
上記のスクリプトを実行すると、割り当てられたパラメータセットの値は変更されず、パラメータが単純に変更されます。
この点についてご協力いただけませんか?
答え1
あなたが直面している問題は、一重引用符()で保護されたawkコマンド内でBASH変数を使用しようとしていることです'...'
。一重引用符内では、bashはない変数を展開すると (例${BI2}
)、awk は文字通り を参照し$6 = "${BI2}"
、6 列目の値をリテラル に設定します"${B12}"
。
幸いなことに、 (別名) 引数を使用して変数awk
から変数を簡単に作成できます。shell
--assign
-v
awk \
-v BI2="${BI2}" \
-v DS2="${DS2}" \
-v DSMAX2="${DSMAX2}" \
-v WS2="${WS2}" \
-v D22="${D22}" \
-v D32="${D32}" \
'{if($1==2)
{
$6 = BI2; $7 = DS2; $8 = DSMAX2; $9 = WS2; $25 =D22; $26 =D32;
}
print $0;
}'
答え2
スクリプトを一重引用符で囲みますawk
。これは、 のように、シェルが awk で定義された変数を置換しようとするのを防ぐため、通常は推奨されます$1
。残念ながら、これはまた、 のように、シェルだけが知っている変数を置換できないことも意味します。代わりに、呼び出しを二重引用符で$BI2
囲むと、次のようになります。awk
awk "{if(\$1==2) {
\$6 = ${BI2}
\$7 = ${DS2}
\$8 = ${DSMAX2}
\$9 = ${WS2}
\$25 = ${D22}
\$26 = ${D32}}
print \$0;}" soil_params > tmp
すると、シェルは などを置き換えます。ただし、などの を使用する${BI2}
変数は、シェルがそれらの値を提供しないように、として記述する必要があります。awk
$1
\$1