Logotipo de Bitdoze

Sed Buscar y Reemplazar: Domina las Técnicas Avanzadas

Domina buscar y reemplazar con sed con ejemplos prácticos: el comando de sustitución (s), patrones regex, edición in-place y consejos de portabilidad GNU vs BSD para 2026.

Dragos

Actualizado Publicado 30 min de lectura

Sed Buscar y Reemplazar: Domina las Técnicas Avanzadas

¿Necesitas buscar y reemplazar texto en archivos sin abrir un editor? El comando s de sed maneja la búsqueda y el reemplazo en una sola línea. Útil para actualizaciones de configuración, limpieza de datos o ediciones por lotes dentro de los flujos de trabajo de los comandos esenciales de Linux.

¿Qué es sed?

sed (Stream Editor) procesa texto línea a línea sin cargar el archivo completo en memoria. Útil para:

  • Automatización y scripts
  • Archivos grandes
  • Hacer piping con otras herramientas Unix
  • Procesamiento por lotes

Esta guía se centra en GNU sed (el predeterminado en Linux) pero cubre las diferencias de macOS/BSD y Alpine/busybox en una sección de portabilidad dedicada.

Otras guías de sed:

Sintaxis básica

El comando de sustitución (s)

bash
sed 's/old/new/' file.txt        # Replace first occurrence per line
sed 's/old/new/g' file.txt       # Replace all occurrences (global)
sed 's/old/new/I' file.txt       # Ignore case (use capital I, portable)

Usa I mayúscula, no i minúscula

La i minúscula funciona en GNU sed pero es ambigua con el comando insert y falla en macOS/BSD. La I mayúscula es la forma portable. Funciona en GNU sed y en macOS Big Sur (11.0) y posteriores.

Delimitadores

Usa delimitadores diferentes cuando tu patrón contiene barras:

bash
sed 's|/old/path|/new/path|g' config.txt
sed 's#http://old#https://new#g' urls.txt

Opciones clave

Opción Función Ejemplo
-i Edita archivos in-place sed -i 's/old/new/g' file.txt
-i.bak Edición in-place con backup sed -i.bak 's/old/new/g' file.txt
-n Suprime la salida por defecto sed -n 's/old/new/p' file.txt
-e Comandos múltiples sed -e 's/old/new/' -e 's/foo/bar/' file.txt

-n + -i trunca archivos

Nunca combines -n y -i en la misma invocación de sed. sed -ni 's/foo/bar/' FILE trunca FILE a cero bytes silenciosamente. El flag -n suprime la salida, y -i escribe esa salida (vacía) de vuelta al archivo. Usa -i.bak solo para una edición in-place segura.

Importante: Prueba sin -i primero. Sed escribe a stdout por defecto.

Ejemplos comunes

Archivos de configuración:

bash
sed 's/localhost/production-server/g' config.ini
sed 's/port=8080/port=80/g' server.conf

Refactorización de código:

bash
sed 's/oldFunction/newFunction/g' script.js
sed 's/var /let /g' legacy.js

Limpieza de datos:

bash
sed 's/,/;/g' data.csv              # Change delimiter
sed 's/  / /g' document.txt         # Fix double spaces
sed 's/\t/ /g' file.txt             # Tabs to spaces (GNU-only, see portability section)

Operaciones con archivos

bash
sed 's/old/new/g' file.txt > newfile.txt   # Save to new file
sed -i 's/old/new/g' file.txt              # Edit in place
sed -i.bak 's/old/new/g' file.txt          # Edit with backup

Reemplazos múltiples

bash
sed -e 's/old1/new1/g' -e 's/old2/new2/g' file.txt
sed 's/old1/new1/g; s/old2/new2/g' file.txt

Consejos de seguridad

  1. Prueba sin -i primero
  2. Usa -i.bak para backups
  3. Verifica con diff original.txt modified.txt
  4. Nunca combines -n con -i (trunca el archivo, mira la advertencia de arriba)

GNU vs BSD vs busybox: sed portable

Tu portátil de desarrollo probablemente corre macOS (BSD sed), tu VPS de producción corre Linux (GNU sed), y tu CI/CD podría correr contenedores Alpine (busybox sed). Un script de sed que funciona en uno puede fallar silenciosamente en otro. Esta sección cubre las diferencias que de verdad rompen cosas.

¿Qué sed estás usando?

Ejecuta sed --version en Linux (GNU sed) o sed --version 2>&1 | head -1 en macOS (BSD sed). En Alpine: sed --help 2>&1 | head -1. Saber qué sabor tienes es el primer paso para escribir scripts portables.

El flag -i

Esta es la ruptura de portabilidad #1 con la que la gente tropieza.

GNU y busybox aceptan un sufijo pegado o -i a secas:

bash
sed -i 's/foo/bar/g' file.txt           # GNU/busybox: works
sed -i.bak 's/foo/bar/g' file.txt       # GNU/busybox: works, creates backup

BSD/macOS requiere el sufijo como argumento separado:

bash
sed -i '' 's/foo/bar/g' file.txt        # macOS: no backup
sed -i '.bak' 's/foo/bar/g' file.txt    # macOS: with backup

Correr sed -i 's/foo/bar/g' file.txt en macOS se traga el script como sufijo y da el error “invalid command code.”

Patrón universal seguro (funciona en todas partes):

bash
sed -i.bak 's/foo/bar/' config.conf && rm config.conf.bak

Extensiones regex

Estas extensiones GNU no hacen nada silenciosamente o se comportan mal en otros sed:

Característica GNU sed BSD/macOS busybox Alternativa portable
\b (límite de palabra) Sí No (no-op silencioso) No (no-op silencioso) Ancla con caracteres circundantes
\w, \s Sí No No [[:alnum:]], [[:space:]]
\<, \> Sí No No [[:<:]]/[[:>:]] solo en BSD
\+ en BRE Sí No (+ literal) No Usa -E y +
\t en regex Sí No (t literal) No Usa tab literal o [[:space:]]
\d No No No Usa [0-9] o [[:digit:]]

\b es la trampa más desagradable. Silenciosamente no coincide con nada, así que tu sustitución parece funcionar pero no hace nada. Sin error, sin advertencia.

Flags y opciones

Característica GNU sed macOS/BSD busybox
I (insensible a mayúsculas) Sí Sí (Big Sur 11.0+) Parcial
-E (regex extendida) Sí Sí (10.13+) Mayormente
--debug Sí (4.6+) No No
--sandbox Sí No No
-z (delimitado por nulo) Sí No No

Wrapper universal de in-place para scripts

Si escribes scripts de sed que corren en múltiples plataformas (CI/CD, dotfiles compartidos, comandos de Docker en Alpine), usa este patrón:

bash
# Works on GNU, macOS, and Alpine busybox
sed -i.bak 's/foo/bar/' config.conf && rm config.conf.bak

Para pipelines de CI, envuélvelo en una función:

bash
sed_inplace() {
    sed -i.bak "$@" && rm -f "${@: -1}.bak"
}

Coincidencia avanzada de patrones con expresiones regulares

Las expresiones regulares son donde sed pasa de simple buscar-y-reemplazar a procesamiento de texto real. Los patrones de abajo cubren lo que de verdad vas a usar.

Elementos básicos de expresiones regulares

Carácter comodín (.):

bash
sed 's/t.st/test/g' filename        # Matches "test", "tast", "t3st", etc.
sed 's/c.t/cat/g' pets.txt          # Matches "cat", "cut", "cot", etc.

Clases de caracteres:

bash
sed 's/[aeiou]/X/g' filename        # Replace any vowel with X
sed 's/[0-9]/N/g' filename          # Replace any digit with N
sed 's/[A-Z]/L/g' filename          # Replace uppercase letters with L

Clases de caracteres predefinidas:

bash
sed 's/[[:digit:]]/N/g' filename    # Replace digits (same as [0-9])
sed 's/[[:alpha:]]/L/g' filename    # Replace letters
sed 's/[[:space:]]/X/g' filename    # Replace whitespace characters

Cuantificadores

Cero o más (*):

bash
sed 's/ab*c/X/g' filename          # Matches "ac", "abc", "abbc", "abbbc"
sed 's/[0-9]*/NUM/g' filename      # Matches empty string or any digits

Uno o más (\+ en BRE):

bash
sed 's/[0-9]\+/NUM/g' filename     # Matches one or more digits (GNU BRE extension)
sed 's/a\+/A/g' filename           # Matches "a", "aa", "aaa", etc.

Cuantificador uno-o-más portable

\+ en regex básica es una extensión GNU. Para scripts portables, usa -E (regex extendida) donde + funciona sin backslash: sed -E 's/[0-9]+/NUM/g' filename.

Ocurrencias exactas (\{n\}):

bash
sed 's/[0-9]\{3\}/XXX/g' filename  # Matches exactly 3 digits
sed 's/a\{2,4\}/A/g' filename      # Matches 2 to 4 'a' characters

Anclas y límites

Anclas de línea:

bash
sed 's/^Error/WARNING/' filename    # Replace "Error" at line start
sed 's/end$/END/' filename          # Replace "end" at line end
sed 's/^$/EMPTY/' filename          # Replace empty lines

Límites de palabra:

bash
sed 's/\bcat\b/dog/g' filename      # Replace whole word "cat" only
sed 's/\btest\b/exam/g' filename    # Avoids matching "testing" or "retest"

\b es una extensión de GNU

En BSD/macOS y busybox sed, \b se trata como un backslash literal + b. La sustitución no hace nada silenciosamente. Sin error, sin advertencia. En macOS, usa [[:<:]] y [[:>:]] para los límites de palabra. Para scripts portables, ancla con caracteres circundantes (espacios, puntuación, límites de línea).

Ejemplos avanzados prácticos

Formateo de números de teléfono:

bash
# Transform (123) 456-7890 to 123-456-7890
sed 's/(\([0-9]\{3\}\)) \([0-9]\{3\}\)-\([0-9]\{4\}\)/\1-\2-\3/g' contacts.txt

Extracción y enmascaramiento de emails:

bash
# Replace email addresses with [EMAIL]
sed 's/[a-zA-Z0-9._%+-]\+@[a-zA-Z0-9.-]\+\.[a-zA-Z]\{2,\}/[EMAIL]/g' data.txt

Conversión de formato de fecha:

bash
# Convert MM/DD/YYYY to YYYY-MM-DD
sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\)/\3-\1-\2/g' dates.txt

Actualización de protocolos URL:

bash
# Change HTTP to HTTPS
sed 's|http://\([^[:space:]]*\)|https://\1|g' urls.txt

Agrupación y referencias hacia atrás

Grupos de captura con \(\) y referencias hacia atrás con \1, \2:

bash
# Swap first and last names
sed 's/\([A-Za-z]*\) \([A-Za-z]*\)/\2, \1/g' names.txt

# Duplicate words detection and removal (GNU-only: uses \b and \+)
sed 's/\b\([a-zA-Z]\+\) \1\b/\1/g' text.txt

# Extract filename from path
sed 's/.*\/\([^\/]*\)$/\1/' paths.txt

Ejemplos de patrones complejos

Procesamiento de logs:

bash
# Extract timestamp from log entries
sed 's/^\[\([0-9-: ]*\)\] .*/\1/' server.log

# Replace IP addresses with [IP]
sed 's/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/[IP]/g' access.log

Refactorización de código:

bash
# Update function calls: oldFunc(param) -> newFunc(param)
sed 's/oldFunc(\([^)]*\))/newFunc(\1)/g' code.js

# Convert 'single-quoted' strings to "double-quoted" (simple case)
sed -E "s/'([^']*)'/\"\1\"/g" script.js

El ejemplo de comillas simples a dobles de arriba maneja casos simples. No maneja comillas simples escapadas (\') dentro de strings. Para eso, usa un parser de verdad o perl.

Expresiones regulares extendidas

Usando el flag -E para patrones mejorados:

bash
# Alternation with |
sed -E 's/(cat|dog|bird)/animal/g' pets.txt

# Simplified quantifiers (no escaping needed)
sed -E 's/[0-9]{3}-[0-9]{2}-[0-9]{4}/XXX-XX-XXXX/g' ssn.txt

# Matching URL protocols
sed -E 's/(http|https):\/\/[^[:space:]]*/[URL]/g' text.txt

Nota: ERE de sed no tiene grupos sin captura ((?:...)). Todo grupo () captura. Usa -E por una sintaxis más limpia, no por comportamiento sin captura.

Prueba y depuración de expresiones regulares

Previsualiza coincidencias antes de reemplazar:

bash
# Show what would be matched
grep 'pattern' filename

# Show line numbers with matches
grep -n 'pattern' filename

# Test with sed's print flag
sed -n 's/pattern/replacement/p' filename

Construye patrones incrementalmente:

bash
# Start simple
sed 's/[0-9]/X/' filename

# Add complexity gradually
sed 's/[0-9]\+/NUM/' filename

# Final complex pattern
sed 's/[0-9]\{3\}-[0-9]\{2\}-[0-9]\{4\}/XXX-XX-XXXX/' filename

Usa --debug para trazar la ejecución (GNU sed 4.6+):

bash
echo 1 | sed --debug 's/1/3/'

Esto imprime el programa sed, anota cada línea de entrada mostrando el espacio PATTERN, y traza cada comando. Es la herramienta más útil para el “¿por qué mi comando sed hizo eso?”. El flag --debug es maduro en GNU sed 4.10. Se arregló un crash que ocurría cuando una etiqueta precedía a la opción.

Debugger externo: sedsed es un depurador y formateador para scripts de sed. Útil para recorrer paso a paso scripts complejos de múltiples comandos.

Advertencia sobre testers online: regex101 y herramientas similares usan PCRE, no POSIX BRE/ERE. Características como lookarounds, cuantificadores no-greedy (*?), y \d no se transfieren a sed. Verifica siempre los patrones con sed de verdad.

Técnicas avanzadas de sed y mejores prácticas

Procesamiento dirigido de líneas

Limita operaciones a rangos de línea específicos:

bash
sed '1,10s/old/new/g' file.txt      # Replace only in lines 1-10
sed '5,$s/old/new/g' file.txt       # Replace from line 5 to end
sed '10s/old/new/g' file.txt        # Replace only on line 10

Apunta líneas por patrón:

bash
sed '/pattern/s/old/new/g' file.txt     # Replace only in lines containing "pattern"
sed '/^#/s/old/new/g' file.txt          # Replace only in comment lines
sed '/ERROR/s/old/new/g' log.txt        # Replace only in error lines

Técnicas de previsualización y prueba

Previsualiza cambios antes de aplicar:

bash
sed -n 's/old/new/p' file.txt           # Show only changed lines
sed 's/old/new/g' file.txt | head -20   # Preview first 20 lines
sed 's/old/new/g' file.txt | diff file.txt -  # Show differences

Prueba con números de línea:

bash
nl file.txt | sed 's/old/new/g'        # Show line numbers for context

Trabajando con caracteres especiales

Escapa caracteres literales:

bash
sed 's/\./DOT/g' file.txt              # Escape literal dots
sed 's/\*/STAR/g' file.txt             # Escape literal asterisks
sed 's/\$/DOLLAR/g' file.txt           # Escape literal dollar signs
sed 's/\//SLASH/g' file.txt            # Escape literal forward slashes

Usa delimitadores alternativos:

bash
sed 's|/old/path|/new/path|g' file.txt     # Use | for paths
sed 's#http://old#https://new#g' file.txt  # Use # for URLs
sed 's@old@new@g' file.txt                 # Use @ as delimiter

Escapa & en el string de reemplazo:

& en el reemplazo significa “toda la coincidencia”. Un & literal en una URL o una reescritura de query-string corromperá tu salida:

bash
echo 'foo' | sed 's/foo/A & B/'    # → "A foo B" (probably not intended)
echo 'foo' | sed 's/foo/A \& B/'   # → "A & B" (literal ampersand)

Esto muerde a la gente cuando reescribe URLs con parámetros de query (&param=value). Escapa siempre el & literal en el reemplazo con \&.

Quoting de shell y sustitución de variables

Cuando los patrones de sed vienen de variables (común en scripts de actualización de config), el quoting del shell se vuelve delicado:

bash
# Single quotes: no variable expansion (safe for literal patterns)
sed 's/old/new/g' file.txt

# Double quotes: variables expand, but /, &, \ in values collide with sed
KEY="old/path"
VAL="new/path"
sed "s|$KEY|$VAL|g" config.txt      # Use | delimiter when values contain /

# Always quote filenames in batch loops
for file in *.txt; do
    sed -i.bak 's/old/new/g' "$file"
done

# Use -- to stop option parsing for filenames starting with -
sed -i.bak 's/old/new/g' -- "-weird-name.txt"

Para más sobre las diferencias de quoting del shell, mira el quoting entre Bash y Zsh.

Procesamiento por lotes de múltiples archivos

Procesa todos los archivos de un tipo:

bash
find . -name "*.txt" -exec sed -i 's/old/new/g' {} \;
find . -name "*.conf" -exec sed -i.bak 's/old/new/g' {} \;

Usando xargs para eficiencia:

bash
find . -name "*.txt" | xargs sed -i 's/old/new/g'
find . -name "*.js" -print0 | xargs -0 sed -i 's/console.log/logger.debug/g'

Bucle por los archivos:

bash
for file in *.txt; do
    sed -i.bak 's/old/new/g' "$file"
    echo "Processed: $file"
done

Archivos de config con symlink

sed -i reemplaza el symlink con un archivo regular, rompiendo el enlace. Usa sed -i --follow-symlinks 's/old/new/' /path/to/symlink en GNU sed para editar el archivo destino. Esto importa para directorios de configuración como /etc/nginx/sites-enabled/. GNU sed 4.10 arregló una condición de carrera TOCTOU en --follow-symlinks.

Para más consejos de procesamiento de texto en Linux, mira cómo extraer texto en la línea de comandos de Linux.

Técnicas avanzadas de patrones

Usando referencias hacia atrás para reemplazos complejos:

bash
# Swap two words
sed 's/\(foo\) \(bar\)/\2 \1/g' file.txt

# Duplicate text
sed 's/\(important\)/\1 \1/g' file.txt

# Rearrange data fields
sed 's/\([^,]*\),\([^,]*\),\([^,]*\)/\3,\1,\2/' data.csv

Operaciones múltiples en secuencia:

bash
sed -e 's/old1/new1/g' -e 's/old2/new2/g' -e 's/old3/new3/g' file.txt

Reemplazos condicionales:

bash
# Replace only if line contains specific pattern
sed '/contains_this/{s/old/new/g;}' file.txt

# Replace in specific sections
sed '/START/,/END/{s/old/new/g;}' file.txt

Optimización de rendimiento

Usa el locale C para trabajo pesado en ASCII:

bash
LC_ALL=C sed -E 's/[0-9]+/NUM/g' bigfile.txt

El locale por defecto hace coincidencia de caracteres consciente de Unicode, que es más lenta. Poner LC_ALL=C fuerza coincidencia de bytes ASCII y puede ser significativamente más rápido en archivos grandes con sustituciones pesadas en regex. Haz benchmark con tus propios datos.

Otros consejos de rendimiento:

bash
# Skip the g flag when you only need the first match per line
sed 's/old/new/' file.txt

# One sed pass with semicolons beats multiple sed processes
sed 's/old1/new1/g; s/old2/new2/g; s/old3/new3/g' file.txt

# Use specific patterns to reduce processing
sed '/pattern/s/old/new/g' file.txt

Estrategias de seguridad y backup

Haz backup siempre de los archivos importantes:

bash
cp original.txt original.txt.backup
sed -i.$(date +%Y%m%d) 's/old/new/g' original.txt

Prueba primero con datos de muestra:

bash
head -100 largefile.txt > sample.txt
sed 's/old/new/g' sample.txt          # Test your pattern
# If good, apply to original:
sed -i.backup 's/old/new/g' largefile.txt

Edición in-place atómica (temp + mv):

sed -i no es verdaderamente atómico. Escribe a un archivo temporal y renombra. Para archivos de configuración críticos, el patrón explícito temp + mv te da más control:

bash
sed 's/old/new/' config.conf > config.conf.tmp && mv config.conf.tmp config.conf

Envuélvelo con un trap para limpieza en caso de fallo:

bash
trap 'rm -f config.conf.tmp' EXIT
sed 's/old/new/' config.conf > config.conf.tmp && mv config.conf.tmp config.conf
trap - EXIT

Compensación: mv cambia el inodo, lo que importa si otro proceso tiene el archivo en mmap o si un file watcher monitoriza cambios de inodo.

Usa control de versiones:

bash
git add file.txt                      # Stage current version
sed -i 's/old/new/g' file.txt         # Make changes
git diff                              # Review changes

Mira los comandos de Git para más sobre usar el control de versiones como red de seguridad.

CI/CD e idempotencia

Sed idempotente en CI/CD

s/old/new/g no es idempotente si new contiene old. Por ejemplo, s/foo/foobar/g corrido dos veces produce foobarbar. Para ediciones de config en CI/CD que se re-ejecutan en cada deploy, protégelo con un patrón de dirección, comprueba primero con grep, o usa una herramienta que sea idempotente de forma nativa.

Códigos de salida:

  • 0: éxito
  • 1: comando o regex inválido
  • 2: no puede abrir el archivo de entrada
  • 4: error de E/S o error de runtime grave

Puedes poner códigos de salida personalizados con q N o Q N (extensión GNU):

bash
# Exit with code 2 if "ERROR" is found
sed '/ERROR/{q 2;}' logfile.txt

Modo sandbox (GNU sed):

bash
sed --sandbox 's/old/new/g' untrusted.txt

--sandbox rechaza los comandos e (ejecutar), w (escribir) y r (leer). Úsalo cuando corres sed sobre entrada no confiable en pipelines.

Procesamiento delimitado por nulo:

bash
find . -name "*.txt" -print0 | xargs -0 sed -i.bak 's/old/new/g'

El flag -z / --null-data (GNU sed) procesa entrada delimitada por NUL, que combina con find -print0 y sort -z para manejar con seguridad nombres de archivo con espacios.

Ejemplos prácticos de flujo de trabajo

Actualizaciones de archivos de configuración:

bash
# Update server configuration across multiple files
find /etc/nginx -name "*.conf" -exec sed -i.backup \
    -e 's/old-server.com/new-server.com/g' \
    -e 's/port 8080/port 80/g' {} \;

Refactorización de código:

bash
# Update function names in JavaScript files
find ./src -name "*.js" -exec sed -i \
    's/oldFunction/newFunction/g' {} \;

Procesamiento de logs:

bash
# Clean and standardize log files
sed -e 's/DEBUG/[DEBUG]/g' \
    -e 's/ERROR/[ERROR]/g' \
    -e 's/INFO/[INFO]/g' app.log > standardized.log

Errores comunes a evitar

  1. Olvidar escapar caracteres especiales. ., *, $, [, \ tienen todos significado especial en regex.
  2. No probar los patrones antes de aplicarlos a archivos importantes. Previsualiza siempre con stdout primero.
  3. Usar reemplazo global cuando solo quieres la primera ocurrencia. Omite el flag g.
  4. No hacer backup de archivos antes de la edición in-place. Usa -i.bak o cp.
  5. Hacer patrones demasiado amplios. Coincidir texto no deseado con .* o un . sin escapar.
  6. Usar escapes solo-GNU en scripts portables. \b, \t, \+ fallan silenciosamente en macOS/Alpine.
  7. Combinar -n con -i. Trunca el archivo a cero bytes.
  8. Olvidar que & en el reemplazo significa “toda la coincidencia”. Escapa el & literal como \&.

Consejos pro

  • Empieza con patrones simples y añade complejidad gradualmente
  • Usa grep para probar tus patrones antes de usarlos en sed
  • Usa --debug (GNU sed 4.6+) para trazar la ejecución cuando los patrones se comportan mal
  • Usa LC_ALL=C para procesamiento más rápido de datos ASCII
  • Mantén una colección de patrones sed probados para reutilizar
  • Documenta las expresiones regulares complejas para referencia futura
  • Sabe cuándo dejar de usar sed. Para ramificaciones, hold space, o slurps multilínea, usa awk o Python.

Conclusión

El comando s de sed es la herramienta correcta para ediciones de texto de una línea orientadas a líneas. Maneja actualizaciones de configuración, limpieza de datos y reemplazos por lotes sin cargar el archivo completo en memoria.

Lo clave a recordar: prueba sin -i primero, usa -i.bak para backups, y sabe qué sabor de sed estás corriendo. GNU sed en Linux, BSD sed en macOS, y busybox sed en Alpine se comportan todos diferente para -i, \b, \t, y el flag I. Escribe el sed para la máquina donde corre.

Para transformaciones complejas que involucren ramificaciones, hold space, o procesamiento multilínea, usa awk o Python en su lugar. Haz siempre backup de tus datos antes de ediciones in-place, y practica incrementalmente con archivos de muestra.