Ich versuche, meine Daten mithilfe von zurückzusetzen awk
. Ich habe Daten mit 54 Spalten, wobei ich sechs der Spaltenwerte mithilfe des folgenden Skripts ändern möchte.
#!/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
meine Daten sehen so aus:
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
wenn ich das obige Skript ausführe, ändert es nicht den Wert des zugewiesenen Parametersatzes, sondern ändert einfach die Parameter, wie Sie sehen können
Können Sie mir diesbezüglich bitte helfen?
Antwort1
Das Problem, mit dem Sie konfrontiert sind, besteht darin, dass Sie versuchen, BASH-Variablen innerhalb des Awk-Befehls zu verwenden, der durch einfache Anführungszeichen ( '...'
) geschützt ist. Innerhalb einfacher Anführungszeichen wird BashnichtErweitern Sie die Variablen (z. B. ${BI2}
), sodass awk sie wörtlich erkennt $6 = "${BI2}"
und den Wert der sechsten Spalte auf den wörtlichen Wert setzt "${B12}"
.
Glücklicherweise können Sie mit dem Argument (auch bekannt als ) ganz einfach awk
Variablen aus Variablen erstellen :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;
}'
Antwort2
Sie setzen das awk
Skript in einfache Anführungszeichen. Dies wird normalerweise empfohlen, da die Shell dadurch nicht versucht, von awk definierte Variablen zu ersetzen, wie $1
. Leider bedeutet dies auch, dass die Shell keine Variablen ersetzen kann, die nur ihr bekannt sind, wie $BI2
. Wenn Sie Ihren awk
Aufruf stattdessen in doppelte Anführungszeichen setzen:
awk "{if(\$1==2) {
\$6 = ${BI2}
\$7 = ${DS2}
\$8 = ${DSMAX2}
\$9 = ${WS2}
\$25 = ${D22}
\$26 = ${D32}}
print \$0;}" soil_params > tmp
dann ersetzt die Shell ${BI2}
usw. Allerdings müssen jetzt die awk
verwendeten Variablen, wie , so geschrieben werden, um zu verhindern, dass die Shell versucht, Werte für sie bereitzustellen.$1
\$1