在 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'

相关内容