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

Tengo el siguiente archivo .txt:

Marco Paolo Antonio 

Quiero leerlo línea por línea, y para cada línea quiero asignarle 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”
  • Realiza algunas tareas con $name
  • Leer segunda línea del archivo
  • Asignar $name = “Paolo”

Lo siguiente (guardar como rr.sh ) lee un archivo pasado como un argumento línea por línea:

 #!/bin/bash while IFS='' read -r line || [[ -n "$line" ]]; do echo "Text read from file: $line" done < "$1" 

Explicación:

  • IFS='' (o IFS= ) evita que se recorte el espacio en blanco inicial / final.
  • -r evita que se interpreten escapes de barra invertida.
  • || [[ -n $line ]] || [[ -n $line ]] evita que se ignore la última línea si no termina con un \n (ya que read devuelve un código de salida distinto de cero cuando encuentra EOF).

Ejecute el script de la siguiente manera:

 chmod +x rr.sh ./rr.sh filename.txt 

....

Te animo a usar la bandera -r para 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 del 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 de 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 
 #! /bin/bash cat filename | while read LINE do echo $LINE done 

Mucha gente ha publicado una solución que está sobre optimizada. No creo que sea incorrecto, pero creo humildemente que será deseable una solución menos optimizada para permitir que todos entiendan fácilmente cómo funciona esto. Aquí está mi propuesta:

 #!/bin/bash # # This program reads lines from a file. # end_of_file=0 while [[ $end_of_file == 0 ]] do read -r line # the last exit status is the # flag of the end of file end_of_file=$? echo $line done < "$1" 

Utilizar:

 filename=$1 IFS=$'\n' for next in `cat $filename` do echo "$next read from $filename" done exit 0 

Si ha configurado IFS diferente, obtendrá resultados extraños.

Si necesita procesar tanto el archivo de entrada como la entrada del usuario (o cualquier otra cosa desde stdin), entonces use la siguiente solución:

 #!/bin/bash exec 3<"$1" while IFS='' read -r -u 3 line || [[ -n "$line" ]]; do read -p "> $line (Press Enter to continue)" done 

Basado en la respuesta aceptada y en el tutorial de redirección de bash-hackers .

Aquí, abrimos el descriptor de archivo 3 para el archivo pasado como el argumento del script y le read a read que use este descriptor como entrada ( -u 3 ). Por lo tanto, dejamos el descriptor de entrada predeterminado (0) conectado a un terminal u otra fuente de entrada, capaz de leer la entrada del usuario.

Para un correcto manejo de errores:

 #!/bin/bash set -Ee trap "echo error" EXIT test -e ${FILENAME} || exit while read -r line do echo ${line} done < ${FILENAME} 

Leí la pregunta como:

“Si quiero leer un archivo usando ¿cómo debo hacer? Quiero hacerlo porque cuando escribí ‘hacer algunas tareas con $ nombre’, quise decir que mis tareas son órdenes esperadas”.

Lea el archivo desde dentro esperarlo:

yourExpectScript:

 #!/usr/bin/expect # Pass in filename from command line set filename [ lindex $argv 0 ] # Assumption: file in the same directory set inFile [ open $filename r ] while { ! [ eof $inFile ] } { set line [ gets $inFile ] # You could set name directly. set name $line # Do other expect stuff with $name ... puts " Name: $name" } close $inFile 

Entonces llámalo así:

 yourExpectScript file_with_names.txt