2016-07-21 15 views
0

ich diesen Block der Einstellung habe:Codeblock ersetzt durch verschachtelte geschweiften Klammern

... 
    server { 
     listen  80 default_server; 
     listen  [::]:80 default_server; 
     server_name _; 
     root   /usr/share/nginx/html; 

     # Load configuration files for the default server block. 
     include /etc/nginx/default.d/*.conf; 

     location/{ 
     } 

     error_page 404 /404.html; 
      location = /40x.html { 
     } 

     error_page 500 502 503 504 /50x.html; 
      location = /50x.html { 
     } 
    } 
} 

ich gesamten Server-Block mit einem anderen Block ersetzt werden soll. Auf der Suche nach AWK oder SED. Ersetzt durch

... 
    server { 
     listen    80; 
     listen    443 ssl; 
     server_name   www.example.com; 
     ssl_certificate  www.example.com.crt; 
     ssl_certificate_key www.example.com.key; 
    } 
} 

Regex Muster, das ich mit der Arbeit fand bei der Auswahl, was ich brauchte. Verwendung von -m (Multiline) -Modifikator. Werkzeug verwendet: Regex101.com

server {(?:[^}]*}[^}])* oder server {[\S\s]*(?=^\s{4}\}$)\s*}

+0

'awk' ist viel besser geeignet, um diese Art von Problem zu lösen. Sind Sie (aus irgendeinem verrückten Grund) verpflichtet, 'sed' zu benutzen? UND, du erkennst, dass es eine erweiterte Verwendung von 'sed' ist, um einen mehrzeiligen Haltebereich aufzubauen, um dann ein Muster gegenzupassen? Viel Glück. – shellter

+0

Das war nicht einmal auf meinem Radar, ich ging von einem der Shell-Skripte, die ich vor langer Zeit geändert hatte, die Serverkonfiguration vornahm und sed verwendete. Vielen Dank. Wird forschen. –

+0

Siehe http://StackOverflow.com/a/38460982/620097 für einige Ideen. (Flag-Variablen) Leider möchten Sie eine ganze separate Datei einlesen (richtig?), Also brauchen Sie etwas mit 'getline()', aber ich habe keine Zeit, es herauszufinden. Aktualisieren Sie Ihre Q mit Ihrem besten Versuch, in awk zu lösen (und ein "Awk" -Tag) und die awk Brigade wird mithelfen. Viel Glück. – shellter

Antwort

1

Dies kann sein, was Sie wollen:

$ cat tst.awk 
braceCnt { 
    if (/{/) { braceCnt++ } 
    if (/}/) { braceCnt-- } 
} 
!braceCnt 
/^[[:space:]]*server[[:space:]]*{/ { 
    print newBlock 
    braceCnt = 1 
} 

$ awk -v newBlock='  listen    80; 
     listen    443 ssl; 
     server_name   www.example.com; 
     ssl_certificate  www.example.com.crt; 
     ssl_certificate_key www.example.com.key;' -f tst.awk file 
... 
    server { 
     listen    80; 
     listen    443 ssl; 
     server_name   www.example.com; 
     ssl_certificate  www.example.com.crt; 
     ssl_certificate_key www.example.com.key; 
    } 
} 

oder wenn Sie es bevorzugen, auf Einrückung/Leerraum angewiesen zu sein, als Klammern zu zählen, würde dies auch funktionieren:

$ cat tst.awk 
inBlock && /^ {4}}/ { inBlock=0 } 
!inBlock 
/^[[:space:]]*server[[:space:]]*{/ { print newBlock; inBlock=1 } 

oder wenn Sie nur die Anzahl der Leerzeichen vor der schließenden Klammer wollen, bevor server die Nummer entsprechen, anstatt hart codiert es 4:

$ cat tst.awk 
inBlock && ($0 ~ "^[[:space:]]{"indent"}}") { inBlock=0 } 
!inBlock 
/^[[:space:]]*server[[:space:]]*{/ { 
    indent = index($0,"s") - 1 
    print newBlock; inBlock=1 
} 

usw. usw .... Es Alles hängt von Ihren Anforderungen ab.

0

wählen}, die vier Räume, bevor sie hat und nichts dahinter auf derselben Linie:

/^\s{4}\}$/m 
Verwandte Themen