Aprende leyendo en orden

Combinar comandos — decidir el flujo según el resultado de grep / awk

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.
Dentro de un script, guarda un conteo en una variable con n=$(grep -c ERROR access.log), suma con total=$(awk '{s+=$1} END{print s}') y bifurca con if [ "$n" -ge 2 ]: un analizador de logs que construyes paso a paso, ilustrado y practicado en una terminal del navegador.

Llamar comandos dentro de un script — pipes y sustitución de comandos

La verdadera fuerza de un script de shell está en que puedes combinar dentro de él comandos comunes como `grep`, `awk`, `sed`, `sort` y `wc`.

Dentro de un script también encadenas comandos con el pipe | y capturas su salida con la sustitución de comandos $(cmd).

Si escribes n=$(grep -c error log.txt), el número de líneas coincidentes que devuelve grep -c se guarda en la variable n.

En una variable también puedes guardar un resultado ya totalizado, como en total=$(awk '{s+=$1} END{print s}' f).

Cuando el resultado de un comando está en una variable, puedes usar ese valor para cambiar el comportamiento del script.

printf 'INFO ok\nERROR disk\nINFO ok\nERROR cpu\n' > sys.log   # crear un archivo de ejemplo
vi count.sh   # abrir en el editor, escribir lo siguiente y guardar con :wq
#   #!/bin/sh
#   n=$(grep -c ERROR sys.log)
#   echo "ERROR count: $n"
chmod +x count.sh
./count.sh                                                      # ERROR count: 2
Guardar un conteo en una variable y bifurcar
n=$(grep -c ERROR access.log)n ≥ 2imprimir avison < 2imprimir OK2 o más1 o menosavisoOK
El conteo de grep -c se guarda en la variable n, y el if toma la rama de aviso cuando es 2 o más y la rama OK en caso contrario.
SintaxisSignificadoEjemplo
n=$(grep -c pat f)Guardar en la variable n el número de líneas coincidentesn=$(grep -c error log.txt)
$(cmd | cmd)Guardar en una variable el resultado de un pipetop=$(sort log.txt | head -1)
if [ "$n" -ge 2 ]; then …Bifurcar según si el conteo es 2 o másif [ "$n" -ge 2 ]; then echo warn; fi

Construye un analizador de logs que cuente los errores con grep -c sobre unos datos con formato de log de acceso e imprima un aviso cuando haya 2 errores o más, y OK en caso contrario.

① Ejecuta printf 'INFO login\nERROR timeout\nINFO logout\nERROR 500\nINFO ping\n' > access.log para crear un archivo de ejemplo.

② Abre scan.sh con vi scan.sh y presiona i para entrar en modo de inserción. Guarda el conteo en una variable con n=$(grep -c ERROR access.log) y luego imprime AVISO: se encontraron $n errores o bien OK con if [ "$n" -ge 2 ]; then … else … fi (pon #!/bin/sh en la primera línea). Cuando termines, presiona Esc:wq para guardar.

③ Añade permiso de ejecución con chmod +x scan.sh, ejecuta ./scan.sh y confirma que sale el aviso.

④ Si no estás seguro de qué escribir, puedes copiar el cuerpo del panel de respuesta y pegarlo en el modo de inserción de vi.

(Ejecútalo correctamente y aparecerá la explicación).

Linux console
0 / 3 completado(s)
Loading Linux Terminal...

Totalizar y cambiar el comportamiento según el resultado — awk y bifurcación

Más allá de los conteos, también puedes sumar números y decidir a partir del total.

total=$(awk '{s+=$1} END{print s}' f) suma la columna 1 de cada línea y guarda ese total en la variable total.

Cuando quieras el número de apariciones de cada palabra, ordena y cuenta con sort f | uniq -c, y luego captura ese resultado con $(...).

Compara la suma con un umbral, como en if [ "$total" -gt 100 ]; then …, y podrás tomar decisiones como avisar cuando el total pase de un límite.

Junta agregación y bifurcación en un solo script y tendrás una herramienta práctica que lee los datos y evalúa la situación.

printf '40\n30\n50\n' > sales.txt   # datos numéricos de una sola columna
vi sum.sh   # abrir en el editor, escribir lo siguiente y guardar con :wq
#   #!/bin/sh
#   total=$(awk '{s+=$1} END{print s}' sales.txt)
#   if [ "$total" -gt 100 ]; then
#     echo "total $total: meta cumplida"
#   else
#     echo "total $total: meta no cumplida"
#   fi
chmod +x sum.sh
./sum.sh                              # total 120: meta cumplida
printf 'a\na\nb\n' > tags.txt   # archivo de ejemplo con palabras repetidas
sort tags.txt | uniq -c          # ordenar primero y luego contar
# salida:
#   2 a
#   1 b
Sumar un total y bifurcar según su valor
total=$(awk … errors.txt)total > 20alertatotal ≤ 20aceptablepor encimadentropor encima del umbraldentro del umbral
El if compara con el umbral 20 el total sumado por awk, y toma la rama de alerta si lo supera y la de aceptable si no.
SintaxisSignificadoEjemplo
awk '{s+=$1} END{print s}' fSumar la columna 1awk '{s+=$1} END{print s}' nums.txt
sort f | uniq -cOrdenar antes de contar las aparicionessort tags.txt | uniq -c
if [ "$total" -gt N ]; then …Bifurcar comparando el total con el umbral Nif [ "$total" -gt 100 ]; then …

Construye un script que sume datos numéricos con awk y cambie su resultado según si pasa o no de un umbral.

① Ejecuta printf '12\n8\n5\n3\n' > errors.txt para crear datos numéricos de una sola columna.

② Abre sum.sh con vi sum.sh y presiona i para entrar en modo de inserción. Guarda la suma en una variable con total=$(awk '{s+=$1} END{print s}' errors.txt) y luego imprime alerta: total $total o bien aceptable: total $total con if [ "$total" -gt 20 ]; then … else … fi (pon #!/bin/sh en la primera línea). Cuando termines, presiona Esc:wq para guardar.

③ Añade permiso de ejecución con chmod +x sum.sh, ejecuta ./sum.sh y confirma que obtienes el resultado bifurcado según el total.

④ Si no estás seguro de qué escribir, puedes copiar el cuerpo del panel de respuesta y pegarlo en el modo de inserción de vi.

Linux console
0 / 3 completado(s)
Loading Linux Terminal...

Redirigir la salida y los errores — > y 2>

A veces quieres que el resultado de un script quede en un archivo en lugar de en pantalla.

./scan.sh > report.txt escribe la salida normal (la salida estándar) en report.txt.

Si envías los mensajes de error al error estándar con echo "..." 1>&2, ./scan.sh > report.txt 2> error.log te permite guardar los resultados correctos y los errores en archivos distintos.

vi job.sh   # abrir en el editor, escribir lo siguiente y guardar con :wq
#   #!/bin/sh
#   echo "proceso iniciado"            # salida estándar
#   echo "nota: entrada sin datos" 1>&2  # error estándar
chmod +x job.sh
./job.sh > out.txt 2> err.txt        # redirigir salida y errores a archivos distintos
cat out.txt                          # proceso iniciado
cat err.txt                          # nota: entrada sin datos
Redirigir la salida y los errores
./scan.shecho: salida (stdout)> report.txt./scan.shecho … 1>&2 (stderr)2> error.logsalida estándarerror estándar
La salida estándar va a > report.txt y el error estándar a 2> error.log, cada uno por su lado.
SintaxisSignificadoEjemplo
cmd > outEscribir la salida estándar en un archivo./scan.sh > report.txt
echo "…" 1>&2Enviar un mensaje al error estándarecho "failed" 1>&2
cmd > out 2> errRedirigir la salida y los errores a archivos distintos./scan.sh > report.txt 2> error.log

Construye un script que redirija un mensaje normal y un mensaje de error a archivos distintos.

① Abre job.sh con vi job.sh y presiona i para entrar en modo de inserción. Envía echo "listo" a la salida estándar y echo "aviso" 1>&2 al error estándar (pon #!/bin/sh en la primera línea). Cuando termines, presiona Esc:wq para guardar.

② Añade permiso de ejecución con chmod +x job.sh y luego separa la salida y los errores en archivos distintos con ./job.sh > out.txt 2> err.txt.

③ Ejecuta cat out.txt y cat err.txt, y confirma que el mensaje normal y el de error cayeron cada uno en su propio archivo.

④ Si no estás seguro de qué escribir, puedes copiar el cuerpo del panel de respuesta y pegarlo en el modo de inserción de vi.

Linux console
0 / 3 completado(s)
Loading Linux Terminal...
QUIZ

Verificación de conocimientos

Responde cada pregunta una a una.

Pregunta 1¿Qué guarda n=$(grep -c error log.txt) en la variable n?

Pregunta 2¿Qué hace if [ "$n" -ge 2 ]; then …?

Pregunta 3En ./scan.sh > report.txt 2> error.log, ¿qué redirige 2>?