シェルスクリプトで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

必要ありませgrepbash

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

しかし、これは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についての依存関係を追加しません。bashsh

おすすめ記事