Yo suelo usar el comando de lectura para leer un archivo de entrada a la secuencia de comandos de shell de línea por línea. Un ejemplo de código como el que a continuación se obtiene un resultado incorrecto si una nueva línea no se ha insertado al final de la última línea en el archivo de entrada, blah.txt.
#!/bin/sh
while read line
do
echo $line
done <blah.txt
Por lo que si el archivo de entrada se lee algo así como –
One
Two
Three
Four
y yo no pulse la tecla de retorno después de Cuatro, el guión falla al leer la última línea, y se imprime
One
Two
Three
Ahora si puedo dejar una línea en blanco después de Cuatro, como,
One
Two
Three
Four
//blank line
la salida se imprime todas las líneas, incluyendo Cuatro. Sin embargo, este no es el caso cuando he leído una línea mediante la cat
comando; todas las líneas, incluida la última que se imprime sin yo tener que agregar una línea en blanco al final.
Alguien tiene ideas sobre por qué sucede esto? Los guiones que cree la mayoría va a ser ejecutado por los demás, por lo que no es necesario que van a agregar una línea en blanco al final de cada archivo de entrada.
He estado tratando de averiguar esto para las edades; apreciaría si usted tiene cualquiera de las soluciones(por supuesto, la cat
comando es uno, pero me gustaría saber la razón detrás de lectura no funciona igual de bien).
read
lee hasta que encuentra un carácter de nueva línea o el final del archivo y devuelve un valor distinto de cero código de salida si se encuentra con un fin-de-archivo. Así que es muy posible que para leer una línea y el retorno distinto de cero código de salida.Por consiguiente, el siguiente código no es seguro si la entrada no podría ser terminado por un salto de línea:
porque el cuerpo de la
while
no ser ejecutado en la última línea.Técnicamente hablando, un archivo no termina con un salto de línea no es un archivo de texto, herramientas de texto y puede fallar de manera extraña en un archivo. Sin embargo, siempre soy reacio a volver a caer en esa explicación.
Una forma de resolver el problema es probar si lo que se lee no está vacía (
-n
):Otras soluciones incluyen el uso de
mapfile
para leer el archivo en una matriz de tuberías, el archivo a través de la utilidad de lo que está garantizado para terminar la última línea correctamente (grep .
, por ejemplo, si usted no quiere tratar con líneas en blanco), o haciendo el proceso iterativo de procesamiento con una herramienta comoawk
(que generalmente es de mi preferencia).Nota que
-r
es casi seguro que se necesita en elread
builtin; haceread
no reinterpretar\
-secuencias en la entrada.grep .
solución. Bonita y sencilla.||
y[[ -n $LINE ]]
significa aquí? ¿||
media O?cmd1 || cmd2
tiene éxito sicmd1
éxito ocmd2
se realiza correctamente. (El éxito significa un código de salida de 0.)read
tiene éxito si se encuentra un carácter de salto de línea;[[
tiene éxito si la prueba de expresión (en este caso$LINE
no está vacío) es verdadera.-n
prueba de la realidad de las pruebas para — comprueba si la longitud de la cadena es distinto de cero. Mismo como[[ ! -z "${LINE}" ]]
.Cómo utilizar `tiempo de leer` (Bash) para leer la última línea de un fichero si no hay salto de línea al final del archivo?
Una línea de respuesta:
IFS
de la shell actual. Y usted no debe leer con líneas deEl uso de tiempo de bucle como este:
O el uso de
grep
con bucle while:Utilizando
grep .
en lugar degrep ""
se omita las líneas vacías.Nota:
Utilizando
IFS=
mantiene una línea de sangría intacta.Usted siempre debe usar la opción-r con la lectura.
No lea las líneas con
para
Archivo sin una nueva línea al final no es un estándar de unix archivo de texto.
A continuación el código con Redirigido «mientras que la lectura de» bucle funciona muy bien para mí