Tengo un comando que devuelve varias líneas. Para un procesamiento adicional, necesito procesar cada línea individual de esas líneas.
Mi código actual funciona modificando el IFS ( separador de campo interno ):
ROWS=$(some command returning multiple lines)
O=$IFS #save original IFS
IFS=$(echo -en "\n\b") # set IFS to linebreak
for ROW in ${ROWS[@]}
do
echo "$ROW"
done
IFS=$O #restore old IFS
Me pregunto, ¿hay una mejor manera de acceder a las líneas individuales de la salida de varias líneas, una sin modificar el IFS? Especialmente la legibilidad de mi script se vuelve mala al modificar el IFS.
Actualización: Tengo problemas para que las respuestas funcionen, por ejemplo, la de choroba:
while IFS= read -r line ; do
let var+=line #line 42
done << $(sqlite3 -list -nullvalue NULL -separator ',' /var/log/asterisk/master.db "${QUERY}")
echo "$var" # line 44
me da
./bla.sh: row 44: Warning: here-document at line 43 delimited by end-of-file (wanted `$(sqlite3 -list -nullvalue NULL -separator , /var/log/asterisk/master.db ${QUERY})')
./bla.sh: row 42: let: echo "": syntax error: invalid arithmetic operator. (error causing character is \"""\").
Alguien me puede ayudar con esto? ¡Gracias!
bash
shell
command
command-substitution
stefan.at.wpf
fuente
fuente
< <(some command returning multiple lines)
, pero eso no es lo que estás haciendo.Respuestas:
¿Qué pasa
read
en unwhile
bucle?Sin embargo, tenga cuidado, la tubería se ejecuta en una subshell, lo que significa que no puede cambiar los valores de las variables para el resto del script. Si necesita algo para sobrevivir de su ciclo while, puede usar la sustitución del proceso de bash:
fuente
bash
, pero vale la pena señalar que el alcance del subshell de las variables es solo un problemabash
, ya que hacer lo mismozsh
no tendría este problema en absoluto.Establecer
IFS
solo una nueva línea no es suficiente. (¿Por qué también se divide en los caracteres de retroceso, por cierto?)En su código,
${ROWS[@]}
(que es una forma extraña de escribir$ROWS
,ROWS
no es una matriz) no se cita entre comillas dobles. (Si estaba entre comillas dobles, obtendría una sola cadena, yaROWS
que no es una matriz). Por lo tanto, el shell divide el valor de la variable en campos en cadaIFS
carácter, luego trata cada campo como un patrón global. Por ejemplo, si una de las líneas impresas por el comando contiene un solo carácter*
, este será reemplazado por los nombres de archivo en el directorio actual.Puedes desactivar el globbing con
set -f
. En la mayoría de los casos en los que configura elIFS
uso de la función de división de campo del shell, también debe desactivar el globbing. Vuelva a encenderlo conset +f
.El idioma confiable para leer la salida de un comando línea por línea es
while IFS= read -r
.Tenga en cuenta que la mayoría de los shells ejecutan cada comando de una tubería en un subshell separado. Entonces, si necesita establecer variables y usarlas después del ciclo, ajuste estos comandos en un grupo junto con el ciclo. (Ksh y zsh son las excepciones, ejecutan el último comando de una tubería en el shell principal).
fuente
Está mezclando la sintaxis here-document y here-string en su pregunta de actualización.
Utilice el documento aquí:
O aquí-cadena:
fuente