シェルスクリプト内でのパターンマッチングに grep と論理演算子を使用する

シェルスクリプト内でのパターンマッチングに grep と論理演算子を使用する

ドメインのリストに対して実行される dig コマンドの出力で特定のパターンを見つけるスクリプトを開発しようとしています。これを行うには grep を使用しますが、複数の論理演算を使用してこれを実装するのが困難です。

私は次のようなことを達成したいと思っています:

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

出力を grep にパイプすることでパターンを機能させることはできました"NXDOMAIN"が、論理演算子を実装する方法がわかりません。これまでの私のスクリプトは次のとおりです。

#!/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しかし、これは 2 つの追加プロセスを生成し、ほとんどの実装では外部ユーティリティを実行することを意味するため、効率が低下します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は への依存関係を追加する必要はありません。bashsh

答え2

再度 grep にパイプすることで論理を作成できANDOR正規表現を使用して論理を作成できます。

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

関連情報