Uso de grep y operadores lógicos para la coincidencia de patrones dentro del script de shell

Uso de grep y operadores lógicos para la coincidencia de patrones dentro del script de shell

Estoy intentando desarrollar un script que encuentre un patrón específico en la salida del comando dig que se ejecuta en una lista de dominios. Para hacer esto, estoy usando grep pero tengo dificultades para implementarlo usando múltiples operaciones lógicas.

Quiero lograr algo como esto:

if output contains ("NXDOMAIN") and ("test1.com" or "test2.com"); then
echo output;

Me las arreglé para que funcione para el patrón "NXDOMAIN"canalizando la salida a grep, pero no sé cómo implementar los operadores lógicos. Mi guión hasta ahora:

#!/bin/bash
input="/root/subdomains.txt"
while IFS= read -r line
do
    output=$(dig "$line")
    if echo "$output" | grep "NXDOMAIN" >&/dev/null; then
        echo "$output";
    else
        echo " " >&/dev/null;
    fi
done < "$input"

¿Usar grep es la mejor manera de lograr esto?

Respuesta1

No hay necesidad de grepo bashaquí.

#!/bin/sh -
input="/root/subdomains.txt"

contains() {
  case "$1" in
    (*"$2"*) true;;
    (*) false;;
  esac
}

while IFS= read <&3 -r line
do
    output=$(dig "$line")
    if
      contains "$output" NXDOMAIN && {
        contains "$output" test1.com || contains "$output" test2.com
      }
    then
      printf '%s\n' "$output"
    fi
done 3< "$input"

Si realmente quisieras usar grep, lo definirías containscomo:

contains() {
  printf '%s\n' "$1" | grep -qFe "$2"
}

Pero eso sería menos eficiente ya que significa generar dos procesos adicionales y, en la mayoría de las implementaciones, ejecutar una utilidad shexterna .grep

O:

#!/bin/sh -
input="/root/subdomains.txt"

match() {
  case "$1" in
    ($2) true;;
    (*) false;;
  esac
}

while IFS= read <&3 -r line
do
    output=$(dig "$line")
    if
      match "$output" '*NXDOMAIN*' &&
        match "$output" '*test[12].com*'
    then
      printf '%s\n' "$output"
    fi
done 3< "$input"

O prescindir de la función intermediaria:

#!/bin/sh -
input="/root/subdomains.txt"

while IFS= read <&3 -r line
do
    output=$(dig "$line")
    case $output in
      (NXDOMAIN)
        case $output in
          (test1.com | test2.com) printf '%s\n' "$output"
        esac
    esac
done 3< "$input"

Eso también funcionaría con bash, pero no es necesario agregar una dependencia bashcuando su estándar (presumiblemente más rápido y eficiente) shpueda hacerlo.

Respuesta2

Puede crear una lógica ANDconectando grep nuevamente y una lógica ORusando expresiones regulares:

echo "$output" | grep "NXDOMAIN" | grep -E 'test1\.com|test2\.com'

información relacionada