Estoy tratando de almacenar varias líneas en una variable bash, pero parece que no funciona.
Por ejemplo, si enumero /binun archivo por línea y lo almaceno $LS, luego lo paso $LScomo stdin wc, siempre devuelve 1:
$ ls -1 /bin | wc -l
134
$ LS=$(ls -1 /bin); wc -l <<< $LS
1
Si intento imprimir en la pantalla, obtengo varios resultados: echoimprime todas las líneas en una sola línea, mientras printfimprime solo la primera línea:
#!/bin/bash
LS=$(ls -1 /bin)
echo $LS
printf $LS
Entonces, ¿una variable bash puede contener varias líneas?

printf "%s\n" $LSlo harían.wcy otros comandos:wc -l <<< "$LS"printf '%s\n' "$LS"si quieres ver nueva línea. Eso está mal escrito, lo arregló!Las nuevas líneas están en la variable.
LS=$(ls -1)establece la variableLSen la salida dels -1(que produce la misma salida quels, por cierto, excepto cuando la salida va a una terminal), menos las nuevas líneas finales.El problema es que está eliminando las nuevas líneas cuando imprime el valor. En un script de shell,
$LSno significa "el valor de la variableLS", significa "tomar el valor deLS, dividirlo en palabras segúnIFSe interpretar cada palabra como un patrón global". Para obtener el valor deLS, necesita escribir"$LS", o más generalmente poner$LSentre comillas dobles.echo "$LS"imprime el valor deLS, excepto en algunos shells que interpretan caracteres de barra invertida, y a excepción de algunos valores que comienzan con-.printf "$LS"imprime el valorLSsiempre que no contenga ningún carácter de porcentaje o barra invertida y (con la mayoría de las implementaciones) no comience con-.Para imprimir el valor de
LSexactamente, useprintf %s "$LS". Si quieres una nueva línea al final, úsalaprintf '%s\n' "$LS".Tenga en cuenta que
$(ls)no es, en general, la lista de archivos en el directorio actual. Esto solo funciona cuando tienes nombres de archivo suficientemente mansos. Para obtener la lista de nombres de archivo (excepto archivos punto), es necesario utilizar un comodín:*. El resultado es una lista de cadenas, no una cadena, por lo que no puede asignarla a una variable de cadena; puede usar una variable de matrizfiles=(*)en shells que las admitan (ksh93, bash, zsh).Para obtener más información, consulte ¿Por qué mi script de shell se ahoga en espacios en blanco u otros caracteres especiales?
fuente
Lo antes mencionado
Es la única solución correcta.
Permítanme demostrar que las otras soluciones propuestas, tanto con
echoyprintf, simplemente no funcionan correctamente:(También se puede probar con
V=$(printf 'line0:\\n\\n\nline1.\n') printf '%s\n' "$V"y variaciones).Mientras que
\nen los nombres de archivo puede no ser tan común, almacenargit diffen una variable, y sus posibilidades de encontrar literales\naumentan dramáticamente.fuente
kshyzshtambién soporteprint -r -- "$LS"yzshtambién tieneecho -E - $LS.cshtieneecho $LS:qsin embargo que no emitirá el carácter de nueva línea Si $ LS está vacía, y conseguir un valor de varias líneas en $ LS en el primer lugar es bastante complicado en CSH.