Leer un archivo línea por línea asignando el valor a una variable [duplicado]

Resuelto Marco asked hace 12 años • 10 respuestas

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"
Marco avatar Jun 07 '12 16:06 Marco
Aceptado

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=(o IFS='') evita que se recorten los espacios en blanco iniciales y finales.
  • -revita 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 readdevuelve 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 readpuede 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 <&3en su lugar).

cppcoder avatar Jun 07 '2012 09:06 cppcoder

Te animo a que uses la -rbandera readque 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"
Grzegorz Wierzowiecki avatar Jun 07 '2012 10:06 Grzegorz Wierzowiecki

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
OneWinged avatar Jun 07 '2012 09:06 OneWinged