Pregunta

Me gustaría usar Sed para expandir variables dentro de un archivo.

Supongamos que exporté una variable VARIABLE = algo, y tengo una " prueba " archivo con lo siguiente:

I'd like to expand this: "${VARIABLE}"

He estado probando comandos como los siguientes, pero fue en vano:

cat test | sed -e "s/\(\${[A-Z]*}\)/`eval "echo '\1'"`/" > outputfile

El resultado es el " archivo de salida " con la variable aún no expandida:

I'd like to expand this: "something"

Aún así, ejecutar eval " echo '$ {VARIABLE}' en la consola bash da como resultado el valor " something " siendo repetido Además, probé y ese patrón realmente se está haciendo coincidir.

El resultado deseado sería

<*>

¿Alguien puede arrojar una luz sobre esto?

¿Fue útil?

Solución

Considere su versión de prueba:

cat test | sed -e "s/\(\${[A-Z]*}\)/`eval "echo '\1'"`/" > outputfile

La razón por la que esto no funciona es porque requiere presciencia por parte del shell. El script sed se genera antes de que sed coincida con cualquier patrón, por lo que el shell no puede hacer ese trabajo por usted.

He hecho esto de varias maneras en el pasado. Normalmente, he tenido una lista de variables conocidas y sus valores, y he hecho la sustitución de esa lista:

for var in PATH VARIABLE USERNAME
do
    echo 's%${'"$var"'}%'$(eval echo "\$var")'%g'
done > sed.script

cat test | sed -f sed.script > outputfile

Si desea asignar variables arbitrariamente, debe tratar con todo el entorno (en lugar de la lista fija de nombres de variables, use el resultado de env , editado adecuadamente) o use Perl o Python en su lugar.

Tenga en cuenta que si el valor de una variable de entorno contiene una barra oblicua en su versión, tendría problemas al usar la barra como separador de campo en la notación s ///. Usé el '%' ya que relativamente pocas variables de entorno usan eso, pero hay algunas que se encuentran en algunas máquinas que contienen caracteres '%' y, por lo tanto, una solución completa es más complicada. También debe preocuparse por las barras invertidas en el valor. Probablemente tenga que usar algo como ' $ (eval echo " \ $$ var " | sed' s / [\%] / \\ & amp; / g ') ' para escapar de las barras invertidas y símbolos de porcentaje en el valor de la variable de entorno. Arrugas finales: algunas versiones de sed tienen (o tenían) una capacidad limitada para el tamaño del script; las versiones anteriores de HP-UX tenían un límite de aproximadamente 100. No estoy seguro de si eso todavía es un problema, pero fue hace tan solo 5 años.

La adaptación simple del guión original dice:

env |
sed 's/=.*//' |
while read var
do
    echo 's%${'"$var"'}%'$(eval echo "\$var" | sed 's/[\%]/\\&/g')'%g'
done > sed.script

cat test | sed -f sed.script > outputfile

Sin embargo, una mejor solución utiliza el hecho de que ya tiene los valores en la salida de env , por lo que podemos escribir:

env |
sed 's/[\%]/\\&/g;s/\([^=]*\)=\(.*\)/s%${\1}%\2%/' > sed.script
cat test | sed -f sed.script > outputfile

Esto es completamente más seguro porque el shell nunca evalúa nada que no deba evaluarse; debe tener mucho cuidado con los metacaracteres del shell en valores variables. Creo que esta versión solo puede tener problemas si alguna salida de env está mal formada, creo.

Cuidado: escribir scripts sed con sed es una ocupación esotérica, pero que ilustra el poder de las buenas herramientas.

Todos estos ejemplos son negligentes al no limpiar los archivos temporales.

Otros consejos

Quizás puedas sobrevivir sin usar sed:

$ echo $VARIABLE
something
$ cat test
I'd like to expand this: ${VARIABLE}
$ eval "echo \"`cat test`\"" > outputfile
$ cat outputfile
I'd like to expand this: something

Deje que la interpolación variable de shell haga el trabajo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top