Nginx conf에서 서버 청크 및 값 추출

Nginx conf에서 서버 청크 및 값 추출

AWK를 사용하여 nginx 서버 블록을 어떻게 추출할 수 있나요? 입력하다

server { # php/fastcgi
listen       80;
server_name  domain1.com www.domain1.com;
access_log   logs/domain1.access.log  main;
root         html;

location ~ \.php$ {
  fastcgi_pass   127.0.0.1:1025;
}
}
server { # simple reverse-proxy
listen       80;
server_name  domain2.com www.domain2.com;
access_log   logs/domain2.access.log  main;

# serve static files
location ~ ^/(images|javascript|js|css|flash|media|static)/  {
  root    /var/www/virtual/big.server.com/htdocs;
  expires 30d;
}

# pass requests for dynamic content to rails/turbogears/zope, et al
location / {
  proxy_pass      http://127.0.0.1:8080;
}
}

어떻게 필요한 값을 일치시키고 각 서버 블록에 대한 줄을 인쇄할 수 있나요?{}

예를 들어

Listen|root|server_name 값을 가져와야 합니다. 원하는 출력은

80 domain1.com www.domain1.com html
80 domain2.com www.domain2.com /var/www/virtual/big.server.com/htdocs

답변1

각 줄에 공백으로 구분된 여러 값이 포함될 수 있으므로 사용하기가 awk약간 까다롭습니다 . 이는 확실히 awk에서 가능하지만 Perl과 같은 것을 사용하는 것이 더 쉽습니다.

$ perl -lne '
    if(/(^| )server / || eof){ 
        print join " ",@ll if $ll[0]; 
        @ll=(); 
    }
    /^(listen|root|server_name)\s+(\S[^;]+)/ && push @ll,$2' file 
80 domain1.com www.domain1.com html
80 domain2.com www.domain2.com /var/www/virtual/big.server.com/htdocs

이는 -lne"입력 파일을 한 줄씩 읽고( ), 후행 줄 바꿈을 제거하고 -n각 호출에 줄 바꿈을 추가하고( ) 각 줄에 제공된 스크립트를 실행하는 것"을 의미합니다.print-l-e

암호:

  • if(/(^| )server / || eof){server: 현재 줄에 공백으로 둘러싸인 단어가 있거나 줄 시작 부분에 단어가 포함되어 있는 경우 이 섹션이 실행됩니다.

  • print join " ",@ll if $ll[0];: 현재 배열에 저장된 항목이 있는 경우 @ll(따라서 배열의 첫 번째 요소가 정의된 경우 $ll[0]) 공백으로 연결된 배열 내용을 인쇄합니다.

  • @ll=();: 다음 서버의 정보를 얻을 수 있도록 배열을 지웁니다.

  • /^(listen|root|server_name)\s+(\S[^;]+)/ && push @ll,$2': 이 줄이 키워드로 시작하고 하나 이상의 공백 문자가 있는 경우 공백이 아닌 첫 번째 문자와 ;줄 끝까지 가능한 한 많은 비문자를 찾아 이 문자를 추가합니다(대괄호는 패턴을 캡처하므로 "this ”는 이제 인쇄용 $2배열로 전송 됩니다.@ll


awk에서 수행하는 (추악한) 방법은 다음과 같습니다.

$ awk '
    (/ server\s*\{/){ 
        if(out){
            print out
        }
        out=""
    } 
    ($1=="listen" || $1=="root" || $1=="server_name"){
        gsub(";",""); 
        $1=""; 
        gsub(/^ */,""); 
        out ? out=out" "$0 : out=$0
    }
    END{print out}' file 
80 domain1.com www.domain1.com html
80 domain2.com www.domain2.com /var/www/virtual/big.server.com/htdocs

답변2

입력 데이터에 값 쌍에 대한 레이블(또는 이름이라고도 함)이 있을 때마다 먼저 아래( )와 같은 매핑 배열을 만든 f[]다음 어떤 조건에서든 원하는 순서로 인쇄할 수 있는 것이 가장 좋습니다. 레이블을 통해 간단히 배열 값에 액세스할 수 있습니다.

예를 들어 POSIX awk를 사용하면 다음과 같습니다.

$ cat tst.awk
(NR > 1) && ($1 == "server") { prt() }
{
    tag = $1
    sub(/[[:space:]]*[^[:space:]]+[[:space:]]+/,"")
    sub(/;$/,"")
    f[tag] = $0
}
END { prt() }

function prt() {
    print f["listen"], f["server_name"], f["root"]
    delete f
}

$ awk -f tst.awk file
80 domain1.com www.domain1.com html
80 domain2.com www.domain2.com /var/www/virtual/big.server.com/htdocs

문자 클래스를 지원하지 않는 POSIX가 아닌 awk를 발견하면 다음 [:space:]으로 바꾸십시오 \t(예: 공백 문자 뒤에 백슬래시가 오는 경우 t).

특정 문제에 대한 출력을 얻는 더 짧은 방법이 있지만 위의 방법을 사용하면 이러한 필드와 원하는 다른 필드를 인쇄, 테스트, 재정렬, 수정하는 등의 유연성을 얻을 수 있습니다.

관련 정보