Cómo leer un archivo línea por línea

Cómo leer un archivo línea por línea

Uno de los errores más comunes en la realización de scripts en Linux surge cuando se desea leer un archivo línea por línea. Se tiende a utilizar el bucle for, que da lugar a una evaluación de cada palabra y no de cada línea, que es lo que se busca. En este artículo mostramos un método más efectivo.

¿Cuál es un ejemplo de código incorrecto?

Con el bucle "for":

for line in $(cat file.txt); do echo "$line" ; done
Esta
Es 
La 
Línea
n°
1
Esta
Es 
La 
Línea
n°
2
Esta
[...]

Como podemos ver, el resultado no es el esperado. La solución consiste en utilizar un bucle “while” asociado al comando interno “read”.

Sin embargo, también podemos obtener el mismo resultado con un bucle “for” si modificamos el valor de la variable "$IFS" (Internal Field Separator, separador de campo interno) antes de ejecutar el bucle. Esto es lo que veremos a continuación.

¿Cuál es el método Bucle while?

Como hemos mencionado más arriba, el bucle “while” sigue siendo el método más apropiado y simple para leer un archivo línea por línea.

Ejemplo

while read line; do 
 echo -e "$line\n"; 
done < file.txt

Que da como resultado:

Esta es la línea n° 1
Esta es la línea n° 2
Esta es la línea n° 3
Esta es la línea n° 4
Esta es la línea n° 5

Trucos

A partir de un archivo estructurado (como una libretas de direcciones o /etc/passwd por ejemplo), también podemos obtener los valores de cada campo y asignarlos a varias variables con el comando “read”. Sin embargo, hay que tener cuidado de asignar a la variable “IFS” el separador de campo adecuado (espacio por defecto).

Ejemplo:

#!/bin/bash
while IFS=: read user pass uid gid full home shell
do
echo -e "$full :\n\
 Pseudo : $user\n\
 UID :\t $uid\n\
 GID :\t $gid\n\
 Home :\t $home\n\
 Shell :\t $shell\n\n"
done < /etc/passwd

Complemento

while read i; do echo -e "parametro : $i"; done < <(echo -e "a\nab\nc")

¿Cuál es el método Bucle for?

Si bien es cierto que el bucle “while” es el método más simple, este tiene un gran inconveniente: elimina el formateado de las líneas y especialmente los espacios y tabulaciones. El bucle “for”, asociado a un cambio de IFS, permite conservar la estructura del documento a la salida.

Sintaxis

oldIFS=$IFS     # conserva el separador de campo
IFS=$'\n'     # nuevo separador de campo, el caracter fin de línea
for línea in $(cat archivo)
do
   comando
done
IFS=$old_IFS     # restablece el separador de campo predeterminado

Linux