Leer un archivo línea por línea asignando el valor a una variable [duplicado]
Tengo el siguiente archivo .txt:
Marco
Paolo
Antonio
Quiero leerlo línea por línea y para cada línea quiero asignar un valor de línea .txt a una variable. Suponiendo que mi variable es $name
, el flujo es:
- Leer la primera línea del archivo
- Asignar
$name
= "Marco" - hacer algunas tareas con
$name
- Leer la segunda línea del archivo
- Asignar
$name
= "Paolo"
Lo siguiente lee un archivo pasado como argumento línea por línea:
while IFS= read -r line; do
echo "Text read from file: $line"
done < my_filename.txt
Esta es la forma estándar para leer líneas de un archivo en un bucle. Explicación:
IFS=
(oIFS=''
) evita que se recorten los espacios en blanco iniciales y finales.-r
evita que se interpreten los escapes de barra invertida.
O puede ponerlo en un script auxiliar de archivo bash, contenido de ejemplo:
#!/bin/bash
while IFS= read -r line; do
echo "Text read from file: $line"
done < "$1"
Si lo anterior se guarda en un script con nombre de archivo readfile
, se puede ejecutar de la siguiente manera:
chmod +x readfile
./readfile filename.txt
Si el archivo no es un archivo de texto POSIX estándar (= no termina con un carácter de nueva línea), el bucle se puede modificar para manejar líneas parciales finales:
while IFS= read -r line || [[ -n "$line" ]]; do
echo "Text read from file: $line"
done < "$1"
Aquí, || [[ -n $line ]]
evita que se ignore la última línea si no termina con a \n
(ya que read
devuelve un código de salida distinto de cero cuando encuentra EOF).
Si los comandos dentro del bucle también leen desde la entrada estándar, el descriptor de archivo utilizado por read
puede cambiarse a otra cosa (evite los descriptores de archivo estándar ), por ejemplo:
while IFS= read -r -u3 line; do
echo "Text read from file: $line"
done 3< "$1"
(Es posible que los shells que no sean Bash no lo sepan read -u3
; utilícelo read <&3
en su lugar).
Te animo a que uses la -r
bandera read
que significa:
-r Do not treat a backslash character in any special way. Consider each
backslash to be part of the input line.
Estoy citando de man 1 read
.
Otra cosa es tomar un nombre de archivo como argumento.
Aquí está el código actualizado:
#!/usr/bin/bash
filename="$1"
while read -r line; do
name="$line"
echo "Name read from file - $name"
done < "$filename"
El uso de la siguiente plantilla Bash debería permitirle leer un valor a la vez de un archivo y procesarlo.
while read name; do
# Do what you want to $name
done < filename