「AND」条件を使用して単純なbashスクリプトを作成しましたが、機能しません。
#!/bin/bash
cat log3.txt | \
while read -r LINE
do
if [[ $LINE =~ Host ]] && [[ $LINE =~ denied ]] ; then echo $LINE;
fi
done
log3.txtの内容です。
Host: abcd.com
Access denied
OR条件を使用するとうまく機能しますが、AND条件を使用したいので、ログに「Host」と「Access Denied」の両方の文字列が含まれている場合は、出力が表示されます。
ベストアンサー1
ループの1つの反復では、while
値は$LINE
同時に存在できません。Host
そして denied
。ファイルのデータを考慮すると、これは不可能です。だから、出力が得られないのです。
これら2つの単語に一致するファイルのすべての行を表示するにはHost
または denied
、grep
代わりに以下を使用してください。
grep -wF -e 'Host' -e 'Access denied' <log3.txt
ここで使用されているオプションは、正規表現の一致()ではなく文字列比較を実行し、部分文字列()の-F
代わりに完全な単語と一致することを保証します。-w
2 つのクエリ文字列が与えられたら、-e
次を含むすべての行を取得します。どのこれら。
両方の単語がファイルに表示される場合にのみ、両方の単語を含む行のみを表示するより高度なクエリを実行するには、プログラムを使用して実行できますawk
。
awk '/Host/ { hostline=$0 } /Access denied/ { deniedline=$0 }
END { if ((hostline != "") && (deniedline != ""))
print hostline; print deniedline; }' <log3.txt
ここで文字列と一致する行を見つけたら、Host
文字列と同じように保存しますAccess denied
。最後に、両方の文字列に何かが含まれている場合はそれを印刷します。
やや同等のシェルコードで:
#!/bin/sh
while IFS= read -r line; do
case $line in
*Host*)
hostline=$line ;;
*"Access denied"*)
deniedline=$line ;;
esac
done <log3.txt
if [ -n "$hostline" ] && [ -n "$deniedline" ]; then
printf '%s\n%s\n' "$hostline" "$deniedline"
fi
case ... esac
ここでは、読み取ったデータを一致させるステートメントを使用します。使用されるパターンは、正規表現ではなくファイル名のワイルドカードパターンです。
関連: