Registros, campos y separadores personalizados en awk
Controle los separadores de campos de entrada y salida para dividir líneas CSV, TSV y de registros en columnas limpias.
Registros, campos y separadores personalizados en awk es una lección gratuita de DevOps Bootcamp en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de DevOps Bootcamp, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de DevOps Bootcamp incluye 4 lecciones en total.
¿Qué son los registros y los campos en awk?
awk lee la entrada línea por línea. Cada línea se denomina registro, y cada fragmento separado por espacios en blanco dentro de esa línea se denomina campo.
$0: el registro actual completo (toda la línea)$1: el primer campo$2: el segundo campo$NF: el último campo (NF= número de campos)
De forma predeterminada, awk separa los campos en cualquier secuencia de espacios en blanco (espacios o tabulaciones). Esto lo hace útil de inmediato para analizar registros, salidas de comandos y datos delimitados por espacios.
#!/usr/bin/env bash
# Show how awk sees records and fields
echo 'alice 30 engineer' | awk '{ print "Name:", $1, "Age:", $2, "Role:", $3 }'
# $NF is always the last field — regardless of how many there are
echo 'one two three four five' | awk '{ print "Last field:", $NF }'El separador de campos de entrada: FS
La variable integrada FS (separador de campos) indica a awk cómo dividir cada registro en campos. Su valor predeterminado es un espacio simple, que activa el modo de separación por espacios en blanco.
Puede establecer FS de dos formas:
- Con la opción
-Fen la línea de comandos:awk -F':' - Dentro de un bloque
BEGIN:BEGIN { FS = ":" }
Ambas formas son equivalentes. El enfoque del bloque BEGIN se prefiere en scripts largos porque mantiene la configuración dentro del propio script, lo que mejora su legibilidad y portabilidad.
#!/usr/bin/env bash
# Parse /etc/passwd using ':' as the field separator
# Field 1 = username, field 3 = UID, field 7 = shell
echo 'root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin' \
| awk -F':' '{ print $1, "UID="$3, "shell="$7 }'Establecer FS en el bloque BEGIN
En scripts de más de una línea, colocar FS dentro de un bloque BEGIN es la práctica habitual. El bloque BEGIN se ejecuta antes de que awk lea cualquier entrada, por lo que el separador está listo para el primer registro.
Este patrón también permite establecer varias variables a la vez, añadir comentarios y mantener la lógica encapsulada en un archivo de script.
Separadores habituales que encontrará en la práctica:
- Dos puntos
::/etc/passwd,/etc/shadow - Tabulación
\t: exportaciones TSV, salida de compiladores - Coma
,: archivos CSV (simples, sin campos entrecomillados) - Barra vertical
|: algunos formatos de registro, volcados de bases de datos
#!/usr/bin/env bash
# awk script using BEGIN to set FS for TSV input
printf 'alice\t30\tengineer\nbob\t25\tdesigner\ncarol\t35\tmanager\n' \
| awk 'BEGIN { FS = "\t" } { printf "%-10s age=%-3s role=%s\n", $1, $2, $3 }'Analizar archivos CSV con awk
CSV (valores separados por comas) es uno de los formatos de datos más habituales en la ingeniería de shell. Establecer FS="," permite que awk trate las comas como delimitadores.
Advertencia importante: el manejo de CSV integrado en awk no tiene en cuenta los campos entrecomillados que contienen comas (por ejemplo, "Smith, John"). Para CSV simples sin comas entrecomilladas, funciona perfectamente. Para archivos CSV conformes con RFC 4180 y con campos entrecomillados, use un analizador CSV específico o miller/csvkit.
Una tarea habitual en la práctica es extraer columnas concretas y filtrar filas por valor; ambas operaciones son triviales con awk una vez establecido FS.
#!/usr/bin/env bash
# Simple CSV: extract name and salary columns, filter salary > 50000
data='name,department,salary
alice,engineering,95000
bob,marketing,48000
carol,engineering,112000
dave,hr,45000'
echo "$data" | awk -F',' '
NR == 1 { next } # skip header row
$3 > 50000 { print $1, "earns", $3 }
'Separadores de campos de varios caracteres y expresiones regulares
El FS de awk no está limitado a un solo carácter: puede ser una expresión regular. Esto resulta muy potente para formatos de registros reales cuyos campos están separados por delimitadores de longitud variable.
Ejemplos de separadores mediante expresiones regulares:
FS = "[,;]": separa por coma o punto y comaFS = "[ \t]+": separa por uno o más espacios o tabulaciones (igual que el valor predeterminado, pero de forma explícita)FS = "::": separa por dos puntos dobles literalesFS = "\\|": separa por el carácter de barra vertical (se debe escapar)
Cuando FS es una expresión regular, awk (gawk) la trata como un patrón, no como una cadena literal.
#!/usr/bin/env bash
# Log lines with mixed delimiters: split on " | " or "::" or ","
# Here we split on one or more spaces or pipe characters
printf '2024-01-15 | ERROR | disk full | /dev/sda1\n2024-01-15 | INFO | startup ok | main\n' \
| awk -F' \\| ' '{ printf "date=%-12s level=%-6s msg=%s\n", $1, $2, $3 }'
# Split on multiple possible delimiters using character class
echo 'alpha,beta;gamma,delta;epsilon' \
| awk -F'[,;]' '{ for(i=1; i<=NF; i++) print i": "$i }'El separador de campos de salida: OFS
OFS (separador de campos de salida) controla qué coloca awk entre los campos al reconstruir un registro con print. Su valor predeterminado es un espacio simple.
La idea clave es la siguiente: OFS solo se inserta entre campos cuando se usa la sintaxis con comas en print o cuando se asigna un valor a un campo y awk reconstruye $0. Si concatena con espacios en el código fuente, no se usa OFS.
print $1, $2, $3: las comas activan OFS entre los camposprint $1 " " $2: espacio explícito; se ignora OFS
Un patrón habitual es leer CSV, transformarlo y escribir TSV estableciendo FS="," y OFS="\t".
#!/usr/bin/env bash
# Convert CSV to TSV using FS and OFS
data='alice,30,engineer
bob,25,designer
carol,35,manager'
echo "$data" | awk 'BEGIN { FS=","; OFS="\t" } { print $1, $2, $3 }'
echo '---'
# OFS also applies when you modify a field — awk rebuilds $0 with OFS
echo 'alice,30,engineer' | awk 'BEGIN { FS=","; OFS=" | " } { $1=$1; print $0 }'Forzar a awk a reconstruir $0 con OFS
Existe un truco sutil pero importante: asignar un valor a cualquier campo (incluso asignarle el campo a sí mismo, $1=$1) obliga a awk a reconstruir $0 uniendo todos los campos con OFS.
Esta es la forma idiomática de reformatear los delimitadores de un registro sin imprimir manualmente cada campo:
- Establezca
FSen el delimitador de entrada - Establezca
OFSen el delimitador de salida deseado - Fuerce la reconstrucción con
$1=$1 - Imprima
$0
Este enfoque funciona con cualquier número de campos y evita escribir explícitamente $1, $2, $3, ....
#!/usr/bin/env bash
# Reformat a pipe-delimited file to comma-separated WITHOUT listing every field
printf 'alice|30|engineer|london\nbob|25|designer|paris\ncarol|35|manager|berlin\n' \
| awk 'BEGIN { FS="|"; OFS="," } { $1=$1; print $0 }'
# Useful when you don't know how many fields there are:
printf 'a|b|c|d|e|f|g\n1|2|3|4|5|6|7\n' \
| awk 'BEGIN { FS="|"; OFS="\t" } { $1=$1; print $0 }'El separador de registros: RS
Al igual que FS divide los campos dentro de un registro, RS (Record Separator) define qué separa unos registros de otros. De forma predeterminada, RS es un salto de línea, por lo que awk procesa una línea cada vez.
Cambiar RS permite procesar registros de varias líneas de forma muy potente:
RS=""— modo párrafo: las líneas en blanco separan los registros (los campos pueden abarcar varias líneas)RS=";"— dividir por punto y coma (útil para volcados de SQL)RS="\n"— salto de línea explícito (el valor predeterminado)
En el modo párrafo (RS=""), FS sigue utilizándose para dividir los campos dentro del registro de varias líneas, y los saltos de línea dentro de un registro también se tratan automáticamente como separadores de campos.
#!/usr/bin/env bash
# Paragraph mode: each blank-line-separated block is one record
# Useful for processing structured text blocks (e.g., stanzas, config sections)
data='Name: Alice
Role: Engineer
City: London
Name: Bob
Role: Designer
City: Paris'
echo "$data" | awk 'BEGIN { RS=""; FS="\n" } {
print "Record", NR":"
for (i=1; i<=NF; i++) print " ", $i
print ""
}'El separador de registros de salida: ORS
ORS (Output Record Separator) se imprime después de cada sentencia print. De forma predeterminada es un salto de línea (\n), por eso cada print aparece en una línea nueva.
Cambiar ORS permite:
- Unir los registros en una sola línea:
ORS=" " - Añadir líneas en blanco entre los registros de salida:
ORS="\n\n" - Crear formatos de salida personalizados, como fragmentos de JSON o XML
Tenga en cuenta que printf no utiliza ORS: solo se aplica a la sentencia print sin formato adicional. Use printf cuando necesite controlar completamente el formato.
#!/usr/bin/env bash
# Join all matching lines onto one line by setting ORS to a space
printf 'apple\nbanana\ncherry\ndate\n' | awk '{ ORS=" " } { print $0 }'
echo # final newline
# Add a blank line after every output record for readability
printf 'alice 30 engineer\nbob 25 designer\ncarol 35 manager\n' \
| awk 'BEGIN { ORS="\n\n" } { print $1, "is a", $3 }'Ejemplo práctico: analizar registros de acceso de Apache
Los registros de acceso de Apache/nginx tienen un formato conocido, con campos separados por espacios. Algunos campos, como la marca de tiempo, contienen espacios y están delimitados por corchetes o comillas, lo que dificulta dividirlos directamente en campos con awk.
Un enfoque práctico consiste en usar un FS basado en una expresión regular que tenga en cuenta la estructura, o extraer campos concretos por posición cuando se conoce el formato exacto.
Los campos del formato de registro combinado son, a grandes rasgos:
- Dirección IP del cliente
- Ident (normalmente
-) - Usuario autenticado (normalmente
-) - Marca de tiempo (entre corchetes; cuenta como un solo token)
- Método+ruta+protocolo de la solicitud (entre comillas)
- Código de estado HTTP
- Bytes de la respuesta
#!/usr/bin/env bash
# Parse a simulated Apache Combined Log Format line
# Extract: IP, status code, bytes, and request path
logs='192.168.1.10 - alice [15/Jan/2024:10:23:45 +0000] "GET /api/users HTTP/1.1" 200 1523
10.0.0.5 - - [15/Jan/2024:10:23:46 +0000] "POST /login HTTP/1.1" 401 89
172.16.0.3 - bob [15/Jan/2024:10:23:47 +0000] "GET /dashboard HTTP/1.1" 200 8741'
echo "$logs" | awk '{
ip = $1
status = $9
bytes = $10
# Extract the request path from the quoted string in field 7
split($7, parts, "/")
path = "/" parts[2]
printf "ip=%-15s status=%s bytes=%-6s endpoint=%s\n", ip, status, bytes, path
}'Combinar FS, OFS, RS y ORS en una canalización
En la práctica de la ingeniería de shell, rara vez se utilizan estos separadores de forma aislada. Un patrón habitual de canalización consiste en usar awk como convertidor de formatos en una etapa intermedia, transformando un formato estructurado en otro.
Aspectos clave al combinar separadores:
- Establezca siempre
FSyOFSjuntos enBEGINal convertir formatos - Use
$1=$1para activar la reconstrucción de$0cuando quiera reformatear todos los campos sin enumerarlos - Cambie
RSúnicamente cuando los registros abarquen realmente varias líneas - Use
ORSpara controlar el espaciado entre los registros de salida - Prefiera
printfpara obtener un formato preciso; useprintcuando resulte conveniente la terminación automática medianteORS
#!/usr/bin/env bash
# Full pipeline: read a colon-delimited file,
# filter rows where field 3 (UID) >= 1000 (real users),
# then output as tab-separated: username, UID, home dir
echo 'root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
alice:x:1001:1001:Alice:/home/alice:/bin/bash
bob:x:1002:1002:Bob:/home/bob:/bin/zsh
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin' \
| awk 'BEGIN { FS=":"; OFS="\t" } $3 >= 1000 { print $1, $3, $6 }'Comprobación de conocimientos: OFS y reconstrucción de campos
Compruebe su comprensión de cómo interactúa OFS con la asignación de campos en awk.
Resumen de la lección: registros, campos y separadores
Ahora tiene un control total sobre cómo awk lee y escribe datos estructurados. Este es un resumen de las cuatro variables de separación:
FS— separador de campos de entrada. Se establece con-Fo enBEGIN. Puede ser un carácter, una cadena o una expresión regular. Valor predeterminado: espacios en blanco.OFS— separador de campos de salida. Se inserta entre los campos en las llamadasprint $1, $2y cuando awk reconstruye$0después de asignar un campo. Valor predeterminado: un solo espacio.RS— separador de registros de entrada. Define qué separa los registros (líneas). Valor predeterminado: salto de línea. Establézcalo como una cadena vacía para activar el modo párrafo.ORS— separador de registros de salida. Se añade después de cadaprint. Valor predeterminado: salto de línea. Cámbielo para unir líneas o añadir espacios.
El patrón más importante que debe recordar es el siguiente: establezca FS y OFS en BEGIN y, después, use $1=$1 para reconstruir $0 siempre que quiera reformatear los delimitadores de todos los campos sin codificar explícitamente sus posiciones. Este patrón funciona con archivos que tengan cualquier cantidad de columnas y constituye la base de las canalizaciones de conversión de formatos basadas en awk.
Preguntas frecuentes
¿La lección «Registros, campos y separadores personalizados en awk» es gratis?
Sí — el texto completo de «Registros, campos y separadores personalizados en awk» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de DevOps Bootcamp, actualiza a CoddyKit PRO. El curso de DevOps Bootcamp incluye 4 lecciones en total.
¿Qué aprenderé en «Registros, campos y separadores personalizados en awk»?
Controle los separadores de campos de entrada y salida para dividir líneas CSV, TSV y de registros en columnas limpias. Practicas DevOps Bootcamp con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar DevOps Bootcamp?
No se requiere experiencia previa. DevOps Bootcamp en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.
¿Cuánto tiempo toma la lección «Registros, campos y separadores personalizados en awk»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de DevOps Bootcamp?
Sí. Cada lección de DevOps Bootcamp incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Registros, campos y separadores personalizados en awk
- Patrones, rangos y bloques BEGIN/END
- Agregación con arrays y agrupación en awk
- Funciones de awk, formato con printf y generación de informes