awk, ¿cómo cambiar el valor del archivo usando conjuntos de parámetros?

awk, ¿cómo cambiar el valor del archivo usando conjuntos de parámetros?

Estoy intentando restablecer mis datos usando awk. Tengo datos de 54 columnas donde quiero cambiar seis de los valores de las columnas usando el siguiente script.

#!/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

mis datos se ven así:

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                                                       

cuando ejecuto el script anterior, no cambió el valor del conjunto de parámetros asignado, sino que simplemente hizo cambios en los parámetros como pueda

¿Podrías ayudarme en este sentido?

Respuesta1

El problema al que se enfrenta es que está intentando utilizar variables BASH dentro del comando awk que está protegido por comillas simples ( '...'). entre comillas simples, bashnoexpanda las variables (por ejemplo ${BI2}), por lo que awk verá literalmente $6 = "${BI2}"y establecerá el valor de la sexta columna en literal "${B12}".

afortunadamente, puedes crear fácilmente awkvariables a partir de shellvariables usando el argumento --assign(también conocido como ):-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;
  }'

Respuesta2

El awkscript se coloca entre comillas simples; esto generalmente se recomienda porque evita que el shell intente sustituir variables definidas por awk, como $1. Desafortunadamente, también significa que el shell no puede sustituir las variables que sólo él conoce, como $BI2. Si en su lugar envuelve su awkinvocación entre comillas dobles:

awk "{if(\$1==2) {
  \$6 = ${BI2}
  \$7 = ${DS2}
  \$8 = ${DSMAX2}
  \$9 = ${WS2}
  \$25 = ${D22}
  \$26 = ${D32}}
  print \$0;}" soil_params > tmp

entonces el shell se reemplazará ${BI2}y tal. Sin embargo, ahora las variables que awkutiliza, como $1, deben escribirse para \$1evitar que el shell intente proporcionarles valores.

información relacionada