Pregunta 1¿Cómo procesa file la construcción while read line; do … done < file?
Leer la entrada — procesar línea por línea con while read
Este artículo forma parte del Curso de Linux, con el que dominarás desde cero habilidades prácticas de Linux, desde los comandos básicos hasta los scripts de shell.
Con while read name age divides data.txt línea por línea en columnas y la formateas, con for f in "$@" procesas en orden los varios archivos pasados como argumentos, y pasas la entrada a read con pipes o here-doc — ilustrado y practicado en una terminal.
Leer un archivo línea por línea — while read
A menudo quieres procesar listas o archivos de configuración línea por línea.
Si escribes while read line; do … done < file, se lee file de arriba abajo una línea cada vez, se mete esa línea en la variable line y se repite el cuerpo de do … done.
No importa cuántas líneas tenga el archivo, el bucle continúa automáticamente hasta la última línea.
read divide la línea recibida por los espacios y puede repartirla en varias variables.
Si escribes while read name age; do …, la primera palabra de cada línea entra en name y la siguiente en age.
Con datos donde se alinean «nombre valor», como una lista, puedes extraer cada columna y darle formato.
printf 'web running\ndb stopped\n' > services.txt # crear un archivo de ejemplo
while read svc state; do # leer línea a línea en svc y state
echo "Servicio $svc esta $state"
done < services.txt # services.txt como entrada
# salida: Servicio web esta running / Servicio db esta stopped
while read name age lee el archivo línea por línea y, separando por espacios, mete la primera palabra en name y la siguiente en age.| Sintaxis | Significado | Ejemplo |
|---|---|---|
while read v; do … done < f | Procesar el archivo f línea por línea con la variable v | while read l; do echo "$l"; done < data.txt |
while read a b; do … | Dividir una línea por espacios en varias variables | while read name age; do echo "$name"; done < data.txt |
Recibir varios archivos por argumentos — "$@" y $(cat f)
Si fijas dentro del script el nombre del archivo a procesar, no podrás usarlo con otro archivo.
Si lo pasas al ejecutar, como ./show.sh a.txt b.txt, $1 es el primer argumento y $2 el segundo.
Todos los argumentos los recibes juntos con "$@".
Si escribes for f in "$@"; do … done, puedes meter los archivos pasados uno a uno en f y procesarlos en orden.
Cuando quieras usar el archivo entero junto como una cadena, lo cargas en una variable con text=$(cat "$f").
El número de argumentos lo sabes con $#, y si es 0 puedes hacer que muestre el modo de uso.
printf 'line A1\nline A2\n' > a.txt # archivo de ejemplo 1
printf 'line B1\n' > b.txt # archivo de ejemplo 2
vi show.sh # abrir en el editor, escribir lo siguiente y guardar con :wq
# #!/bin/sh
# for f in "$@"; do
# echo "--- $f ---"
# cat "$f"
# done
chmod +x show.sh
./show.sh a.txt b.txt # mostrar los 2 archivos en orden con encabezado
$1 $2, y con "$@" los recibes juntos y los procesas uno a uno con for.| Sintaxis | Significado | Ejemplo |
|---|---|---|
for f in "$@"; do … | Procesar en orden cada archivo de los argumentos | for f in "$@"; do cat "$f"; done |
$(cat f) | Cargar el archivo entero en una sola cadena | text=$(cat data.txt) |
$# | Número de argumentos (si es 0, mostrar el uso) | [ "$#" -eq 0 ] && echo usage |
Entrada interactiva y por pipe — read y here-doc
read no solo lee archivos, también lee la entrada que teclea una persona o la que se pasa por un pipe.
Hay formas como encadenar con un pipe al estilo echo hi | read v, o pasar de golpe la entrada del momento con un here-doc <<'EOF' … EOF.
Es la base para combinar tu script con otros comandos.
# leer línea por línea la salida de un pipe
printf 'one\ntwo\n' | while read v; do echo "linea: $v"; done
# pasar la entrada del momento con un here-doc
while read v; do echo "valor: $v"; done <<'EOF'
x
y
EOF
# entrada manual una sola vez (teclea name y pulsa Enter)
# al ejecutar queda a la espera de entrada
read name; echo "Hola $name"
while read línea por línea con un pipe o un here-doc.| Sintaxis | Significado | Ejemplo |
|---|---|---|
cmd | while read v; do … | Procesar línea por línea la salida de un pipe | cat data.txt | while read l; do echo "$l"; done |
<<'EOF' … EOF | Pasar la entrada del momento con un here-doc | while read l; do echo "$l"; done <<'EOF' |
Verificación de conocimientos
Responde cada pregunta una a una.
Pregunta 2¿Qué notación representa juntos todos los argumentos pasados al script?
Pregunta 3¿Cómo procesas con read línea por línea la salida de un comando sin crear un archivo?