insertar un token al analizar un archivo - bash

2

Tengo un archivo con esta estructura:

ma${token}jid-azimi-865131021
javad-ya${token}rip-865132012

y aquí está mi programa:

IFS="-"

token="12345678"

cat input.txt | while read col1 col2 col3; do
    echo ${col1}
    echo ${col2}
    echo ${col3}
    echo "********************************"
done 

Quiero insertar ${token}mientras leo el archivo. porque token es una palabra dinámica y no puedo cambiarla dentro del archivo cada vez. Entonces agrego ${token}al archivo una vez. Pero el resultado del programa es:

ma${token}jid
azimi
865131021
********************************
javad
ya${token}rip
865132012
********************************

¿Por qué está pasando esto? ma${token}jiddebe expandirse así:, echo ma${token}jidluego 12345678debe insertarse.

Majid Azimi
fuente

Respuestas:

1

El valor de col1es la cadena de 13 caracteres ma${token}jid. Cuando escribe echo ${col1}sin comillas, el shell reemplaza ${col1}por el valor de la variable, luego realiza la división de palabras (es decir, divide el valor en palabras separadas en $IFScaracteres) y la generación de nombre de archivo (es decir, globalización). Los valores variables no se expanden recursivamente utilizando la sintaxis de shell. Si usa comillas dobles alrededor de la sustitución de variables (que debe hacer a menos que tenga una buena razón para no hacerlo), se "$col1"expande directamente al valor de col1.

Si sus cadenas son lo suficientemente mansas (es decir, no contienen caracteres especiales de shell, aparte del ${token}que desea sustituir), puede construir una cadena a partir de la $col1que evalúa como un fragmento de shell. En su ejemplo, se imprimirá la siguiente línea ma12345678jid:

eval "echo $col1"

Alternativamente, reemplace el marcador ${token}por el valor deseado. Puedes hacerlo con una sustitución de cadena en bash:

while read -r col1 col2 col3; do
    echo "${col1//'${token}'/$token}"
    echo "${col2}"
    echo "${col3}"
    echo "********************************"
done <input.txt

También puede hacerlo awk, como un paso previo o posterior al procesamiento (dependiendo de si desea realizar el reemplazo también en otras columnas).

<input.txt awk -v repl="$token" '{gsub(/\${token}/, repl); print}' |
while read 

Puede realizar el reemplazo con sed, pero solo si está seguro de que ninguno de los caracteres &\/y la nueva línea aparecen en el texto de reemplazo $token(puede cambiar el carácter separador de /a otra cosa si hay otro carácter que está seguro de que no aparece en $token).

<input.txt sed -e "s/\\\${token}/$token/" |
while read 
Gilles
fuente
3

Las variables cuando se repiten no están sujetas a expansión variable. Anteponer evala echo. Esto podría funcionar para casos simples, pero puede romperse si sus cadenas contienen |o comillas. O simplemente haz la sustitución:

echo ${col1/'${token}'/$token}
choroba
fuente