ドメインのリストに対して実行される 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
は への依存関係を追加する必要はありません。bash
sh
答え2
再度 grep にパイプすることで論理を作成できAND
、OR
正規表現を使用して論理を作成できます。
echo "$output" | grep "NXDOMAIN" | grep -E 'test1\.com|test2\.com'