跨多行的模式匹配

跨多行的模式匹配

当分布在多行输出中时,验证模式“301 domaname.com 200”是否存在于 BASH 中的快速且简单的方法是什么?

我正在使用类似以下的东西:

 awk '/301|domain.com|200/'
 pcregrep -M '301|domain\.com|200'

但顺序并不重要。我不知道如何表述,所以确实如此。我认为有效的方法显然不是捕捉行尾。

pcregrep -M '301.*domain\.com.*200'

背景:

我正在构建一个小型 mod_rewrite 服务器,我需要一种方法来监视哪些域被重定向到哪些目的地。

因此,我正在组装一个小型 Nagios 检查脚本来为我处理这个问题。

到目前为止我所拥有的是以下内容:

curl qa-mod-rewrite.domain.com -i -I -L

HTTP/1.1 301 Moved Permanently
Via: 1.1 GREGORY
Connection: close
Proxy-Connection: close
Date: Thu, 14 Nov 2013 16:35:19 GMT
Location: http://qa.domain.com/
Content-Type: text/html; charset=iso-8859-1
Server: Apache/2.2.3 (CentOS)

HTTP/1.1 200 OK
Via: 1.1 GREGORY
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Content-Length: 56772
Expires: -1
Date: Thu, 14 Nov 2013 16:35:03 GMT
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.5
Cache-Control: no-cache, no-store
Pragma: no-cache
X-AspNet-Version: 2.0.50727
Set-Cookie: cfcausa.qa#sc_wede=1; path=/
Set-Cookie: ASP.NET_SessionId=i4z1c4ahqoiw13552z413hbs; path=/; HttpOnly
X-Powered-By: ASP.NET

答案1

那里存在误报的范围,例如301.*domain\.com.*200匹配:

HTTP/1.1 404 未找到
内容长度:3010
X-Pingback:http://blah.域名.com/xmlrpc
最后修改时间:11 月 14 日星期四2009 19:27:05(格林威治标准时间)

您可以更彻底一点,例如编写:

curl -sIL http://qa-mod-rewrite.domain.com |
  tr -d '\r' |
  awk -v RS= '
    NR == 1 && $2 == "301" && /\nLocation: [^\n]*domain\.com/ {redir=1}
    $2 == "200" {end=1}
    END {exit !(redir*end)}'

对于可变数据:

url=$1
EXPECTED_REDIRECTION=$2
EXPECTED_REDIRECTION_CODE=$3
EXPECTED_TERMINAL_CODE=$4
export EXPECTED_REDIRECTION EXPECTED_REDIRECTION_CODE EXPECTED_TERMINAL_CODE

curl -sIL "$url" |
  tr -d '\r' |
  awk -v RS= '
    BEGIN {
      re = ENVIRON["EXPECTED_REDIRECTION"]
      gsub(/[][^.$+?\\()]/, "\\&",re)
      re = "\nLocation: [^\n]*" re
    }
    NR == 1 && $2 == ENVIRON["EXPECTED_REDIRECTION_CODE"] && $0 ~ re {redir=1}
    $2 == $ENVIRON["EXPECTED_TERMINAL_CODE"] {end=1}
    END {exit !(redir*end)}'

答案2

你和 很亲近pcregrep。您需要在您的模式中明确包含\nwith.

pcregrep -M '301(.|\n)*domain\.com(.|\n)*200'

答案3

您也可以直接在 Perl 和段落模式 (-000) 中执行此操作:

perl -000ne 'print if /301/' file

这给出了在运行时的预期输出精确的您发布的文件,但可能需要根据您的实际输入进行调整。

答案4

感谢所有回复。我正在研究的另一个替代方案如下。

TMPFILE=$(mktemp)
curl $1 -i -I -L -s > $TMPFILE
cat $TMPFILE
echo ===================
pcregrep -M "1.1 301 Moved(.|\n)*Location: http(|s)://$2(.|\n)*1.1 200 OK" $TMPFILE > /dev/null 2>&1
STATUS=$?
echo $STATUS
rm $TMPFILE
exit $STATUS

相关内容