여러 줄에 걸친 패턴 일치

여러 줄에 걸친 패턴 일치

여러 줄의 출력에 분산되어 있을 때 BASH에 "301 domaname.com 200" 패턴이 존재하는지 확인하는 빠르고 쉬운 방법은 무엇입니까?

나는 다음과 같은 것을 사용하고 있습니다 :

 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-핑백: http://blah.도메인 이름.com/xmlrpc
최종 수정일: 11월 14일 목요일2009 19:27:05 (GMT)

예를 들어 다음과 같이 좀 더 철저하게 작성할 수 있습니다.

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

관련 정보