¿Cómo se itera correctamente sobre las líneas en bash, ya sea en una variable o desde la salida de un comando? Simplemente establecer la variable IFS en una nueva línea funciona para la salida de un comando, pero no cuando se procesa una variable que contiene nuevas líneas.
Por ejemplo
#!/bin/bash
list="One\ntwo\nthree\nfour"
#Print the list with echo
echo -e "echo: \n$list"
#Set the field separator to new line
IFS=$'\n'
#Try to iterate over each line
echo "For loop:"
for item in $list
do
echo "Item: $item"
done
#Output the variable to a file
echo -e $list > list.txt
#Try to iterate over each line from the cat command
echo "For loop over command output:"
for item in `cat list.txt`
do
echo "Item: $item"
done
Esto da la salida:
echo:
One
two
three
four
For loop:
Item: One\ntwo\nthree\nfour
For loop over command output:
Item: One
Item: two
Item: three
Item: four
Como puede ver, hacer eco de la variable o iterar sobre el catcomando imprime cada una de las líneas correctamente una por una. Sin embargo, el primer bucle for imprime todos los elementos en una sola línea. ¿Algunas ideas?

Respuestas:
Con bash, si desea incrustar nuevas líneas en una cadena, encierre la cadena con
$'':Y si ya tiene una cadena de este tipo en una variable, puede leerla línea por línea con:
fuente
done <<< "$list"es crucialdone <<< "$list"es crucial porque eso pasará "$ list" como la entrada aread$listson muy cruciales.echo "$list" | while ...podría parecer más claro que... done <<< "$line"Puedes usar
while+read:Por cierto. La
-eopciónechono es estándar. Use en suprintflugar, si desea portabilidad.fuente
<<<versión sugerida por Glenn Jackman no funciona con la asignación de variables.whilepieza. La<<<versión no lo hace (en nuevas versiones de bash, al menos).fuente
IFS=$'\n'para el mismo efecto.Aquí hay una forma divertida de hacer tu bucle for:
Un poco más sensible / legible sería:
Pero eso es demasiado complejo, solo necesitas un espacio allí:
Usted
$linevariable no contiene saltos de línea. Contiene instancias de\seguido porn. Puedes ver eso claramente con:La sustitución está reemplazando aquellos con espacios, lo cual es suficiente para que funcione en bucles:
Manifestación:
fuente
crpuedes usar$'\n'.También puede convertir primero la variable en una matriz, luego iterar sobre esto.
Esto solo es útil si no desea meterse con el comando
IFSy también tiene problemas con elreadcomando, ya que puede suceder, si llama a otro script dentro del bucle, ese script puede vaciar su búfer de lectura antes de regresar, como me sucedió a mí .fuente