在 shell 腳本中使用 grep 和邏輯運算子進行模式匹配

在 shell 腳本中使用 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"
}

但這會降低效率,因為這意味著產生兩個額外的進程,並且在大多數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'

相關內容