Usando grep e operadores lógicos para correspondência de padrões em shell script

Usando grep e operadores lógicos para correspondência de padrões em shell script

Estou tentando desenvolver um script que encontre um padrão específico na saída do comando dig em execução em uma lista de domínios. Para fazer isso estou usando o grep, mas estou tendo dificuldade em implementá-lo usando várias operações lógicas.

Eu quero conseguir algo assim:

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

Consegui fazê-lo funcionar para o padrão "NXDOMAIN"canalizando a saída para o grep, mas não sei como implementar os operadores lógicos. Meu roteiro até agora:

#!/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 é a melhor maneira de conseguir isso?

Responder1

Não há necessidade de grepou bashaqui.

#!/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"

Se você realmente quisesse usar grep, você definiria containscomo:

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

Mas isso seria menos eficiente, pois significa gerar dois processos extras e, na maioria das implementações, executar um utilitário shexterno .grep

Ou:

#!/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"

Ou dispense a função intermediária:

#!/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"

Isso também funcionaria bash, mas não há necessidade de adicionar uma dependência para bashquando seu padrão (presumivelmente mais rápido e mais enxuto) shpuder fazer isso.

Responder2

Você pode criar uma lógica ANDcanalizando para grep novamente e uma lógica ORusando expressões regulares:

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

informação relacionada