
Contenido de file.txt (sin rarezas, archivo de texto según lo definido por POSIX)
iguana
gecko
anole
Guión de muestra:
#!/bin/sh
string="$(cat file.txt)"
printf '%s' "$string"
Salida de muestra:
[coolguy@somemachine ~]$ ./script.sh
iguana
gecko
anole[coolguy@somemachine ~]$
¿Qué pasó con la última nueva línea? ¿Por qué se conservan todas las nuevas líneas excepto la última? Parece que no deberíamos tener que usar echo para agregar una nueva línea si ya debería haber una allí.
Respuesta1
No es la impresión, es la sustitución del comando lo que hace eso. Está definido para hacer eso. Desde eldescripción POSIX:
El shell ampliará la sustitución del comando ejecutando el comando en un entorno de subshell y reemplazando la sustitución del comando con la salida estándar del comando.eliminar secuencias de uno o más caracteres {newline} al final de la sustitución.
Tenga en cuenta que eliminatodonuevas líneas finales, no solo una.
En un caso algo común, usarías la sustitución de comandos para capturar una salida de una línea, por ejemplo osrev=$(uname -r)
. Las utilidades normalmente imprimen una nueva línea al final, para comodidad del usuario, en la línea de comando. Pero en un script de shell, es posible que quieras usar esa cadena como parte de otra, digamos un nombre de archivo: filename=blahblah-$osrev.dat
. Y en ese caso, la nueva línea final sólo sería una molestia.
Y, por supuesto, un simple echo
agregará una nueva línea final en cualquier caso.
Si desea que el contenido del archivo tal como está en la variable, entonces la solución común es agregar un carácter adicional en la sustitución del comando y eliminarlo más tarde:
printf "foo\nbar\n\n" > file
string=$(cat file; echo x)
string=${string%x}
printf '%q\n' "$string"
que genera $'foo\nbar\n\n'
, mostrando ambas nuevas líneas finales presentes.
Dependiendo de lo que pretenda hacer con los datos, puede haber otras formas. Por ejemplo, un while read
bucle, o Bash mapfile
, si desea procesar el archivo línea por línea.