0Pricing
Linux Command Line & Bash Scripting Mastery · Lección

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 Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Linux Command Line & Bash Scripting Mastery 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 -F en 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 coma
  • FS = "[ \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 literales
  • FS = "\\|": 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 campos
  • print $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 FS en el delimitador de entrada
  • Establezca OFS en 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:

  1. Dirección IP del cliente
  2. Ident (normalmente -)
  3. Usuario autenticado (normalmente -)
  4. Marca de tiempo (entre corchetes; cuenta como un solo token)
  5. Método+ruta+protocolo de la solicitud (entre comillas)
  6. Código de estado HTTP
  7. 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 FS y OFS juntos en BEGIN al convertir formatos
  • Use $1=$1 para activar la reconstrucción de $0 cuando quiera reformatear todos los campos sin enumerarlos
  • Cambie RS únicamente cuando los registros abarquen realmente varias líneas
  • Use ORS para controlar el espaciado entre los registros de salida
  • Prefiera printf para obtener un formato preciso; use print cuando resulte conveniente la terminación automática mediante ORS
#!/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 -F o en BEGIN. 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 llamadas print $1, $2 y cuando awk reconstruye $0 despué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 cada print. 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 Linux Command Line & Bash Scripting Mastery, actualiza a CoddyKit PRO. El curso de Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery?

No se requiere experiencia previa. Linux Command Line & Bash Scripting Mastery 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 Linux Command Line & Bash Scripting Mastery?

Sí. Cada lección de Linux Command Line & Bash Scripting Mastery 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

  1. Registros, campos y separadores personalizados en awk
  2. Patrones, rangos y bloques BEGIN/END
  3. Agregación con arrays y agrupación en awk
  4. Funciones de awk, formato con printf y generación de informes
← Volver a Linux Command Line & Bash Scripting Mastery