Recorrer un fichero línea a línea en Shell Script

Es muy habitual que tengamos que recorrer leer línea a línea un fichero cuando estamos automatizando procesos. En Shell Script lo podemos hacer de diferentes maneras, veamos dos de ellas y cuándo usar una u otra en función de si necesitamos respetar la sangría o no.

Una opción sencilla sería:

#!/bin/bash

let number=0
while read line
do
    let number++
    echo "Línea $number: $line"
done < violante.txt

Que, con un fichero simple, nos devuelve:

Línea 1: Un soneto me manda hacer Violante
Línea 2: que en mi vida me he visto en tanto aprieto;
Línea 3: catorce versos dicen que es soneto;
Línea 4: burla burlando van los tres delante.
Línea 5: 
Línea 6: Yo pensé que no hallara consonante,
Línea 7: y estoy a la mitad de otro cuarteto;
Línea 8: mas si me veo en el primer terceto,
Línea 9: no hay cosa en los cuartetos que me espante.
Línea 10: 
Línea 11: Por el primer terceto voy entrando,
Línea 12: y parece que entré con pie derecho,
Línea 13: pues fin con este verso le voy dando.
Línea 14: 
Línea 15: Ya estoy en el segundo, y aun sospecho
Línea 16: que voy los trece versos acabando;
Línea 17: contad si son catorce, y está hecho.

El problema viene cuando recorremos un script o cualquier otro fichero que tiene tabulaciones o espacios en blanco, que nos los quita. Si en lugar del soneto de Lope recorriésemos con el mismo código un script, nos devolvería algo así:

Línea 1: #!/bin/bash
Línea 2: 
Línea 3: if [ "${variable+x}" ]
Línea 4: then
Línea 5: echo La variable existe
Línea 6: else
Línea 7: echo La variable no existe
Línea 8: fi
Línea 9: 
Línea 10: variable=
Línea 11: 
Línea 12: if [ "${variable+x}" ]
Línea 13: then
Línea 14: echo La variable existe
Línea 15: else
Línea 16: echo La variable no existe
Línea 17: fi

Si no nos da igual el formato y queremos respetar los espacios en blanco y las tabulaciones, deberemos modificar el separador de palabras, que en GNU/Linux se le llama IFS:

#!/bin/bash

let number=0
while IFS= read -r line
do
    let number++
    echo "Línea $number: $line"
done < existevariable.sh

Y ahora sí que nos devuelve el contenido del fichero con las sangrías:

Línea 1: #!/bin/bash
Línea 2: 
Línea 3: if [ "${variable+x}" ]
Línea 4: then
Línea 5: 	echo La variable existe
Línea 6: else 
Línea 7: 	echo La variable no existe
Línea 8: fi
Línea 9: 
Línea 10: variable=
Línea 11: 
Línea 12: if [ "${variable+x}" ]
Línea 13: then
Línea 14: 	echo La variable existe
Línea 15: else 
Línea 16: 	echo La variable no existe
Línea 17: fi

Ahora ya sabemos dos formas de recorrer línea a línea un fichero. Usar una u otra sólo dependerá de si necesitamos o no respetar el sangrado de las líneas.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.