Verwenden von grep und logischen Operatoren für die Musterübereinstimmung innerhalb von Shell-Skripten

Verwenden von grep und logischen Operatoren für die Musterübereinstimmung innerhalb von Shell-Skripten

Ich versuche, ein Skript zu entwickeln, das ein bestimmtes Muster in der Ausgabe des Dig-Befehls findet, der für eine Liste von Domänen ausgeführt wird. Dazu verwende ich grep, habe aber Schwierigkeiten, dies mit mehreren logischen Operationen zu implementieren.

Ich möchte so etwas erreichen:

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

Ich habe es geschafft, es für das Muster zum Laufen zu bringen, "NXDOMAIN"indem ich die Ausgabe in grep weitergeleitet habe, aber ich weiß nicht, wie ich die logischen Operatoren implementieren soll. Mein bisheriges Skript:

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

Ist die Verwendung von grep der beste Weg, dies zu erreichen?

Antwort1

Hier ist kein Bedarf für grepoder bashvorhanden.

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

Wenn Sie wirklich verwenden möchten grep, würden Sie containses wie folgt definieren:

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

Dies wäre jedoch weniger effizient, da dadurch zwei zusätzliche Prozesse erstellt und in den meisten shImplementierungen ein externes grepDienstprogramm ausgeführt werden müsste.

Oder:

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

Oder verzichten Sie auf die Vermittlerfunktion:

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

Dies würde auch mit funktionieren bash, aber es besteht keine Notwendigkeit, eine Abhängigkeit hinzuzufügen, bashwenn Ihr (vermutlich schnellerer und schlankerer) Standard shdies kann.

Antwort2

Sie können eine logische Funktion erstellen, ANDindem Sie erneut eine Weiterleitung an grep durchführen, und eine logische Funktion ORmithilfe regulärer Ausdrücke:

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

verwandte Informationen