Использование grep и логических операторов для сопоставления с шаблоном в скрипте оболочки

Использование grep и логических операторов для сопоставления с шаблоном в скрипте оболочки

Я пытаюсь разработать скрипт, который находит определенный шаблон в выводе команды dig, запущенной против списка доменов. Для этого я использую grep, но у меня возникли трудности с реализацией этого с использованием нескольких логических операций.

Я хочу добиться чего-то вроде этого:

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

Мне удалось заставить его работать для шаблона, "NXDOMAIN"передав вывод в grep, но я не понимаю, как реализовать логические операторы. Мой скрипт на данный момент:

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

Является ли использование grep лучшим способом добиться этого?

решение1

Здесь нет необходимости в grep«или» bash.

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

Если бы вы действительно хотели использовать grep, вы бы определили containsтак:

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

Но это было бы менее эффективно, поскольку означало бы создание двух дополнительных процессов и в большинстве shреализаций запуск внешней grepутилиты.

Или:

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

Или обойтись без посреднической функции:

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

Это также будет работать с bash, но нет необходимости добавлять зависимость, bashесли ваш (предположительно более быстрый и компактный) стандарт shможет это сделать.

решение2

Вы можете создать логический запрос AND, снова перейдя по конвейеру в grep, и логический запрос, ORиспользуя регулярные выражения:

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

Связанный контент