2017-09-27 16 views
1

Ich habe eine große Datei mit Inhalt durch Kopfzeilen getrennt.Substitution zwischen zwei Mustern mit Zeilenversatz über sed oder awk

Wie würde ich gehen über das Ersetzen des Textes zwischen der Zeile nach einem bestimmten Header und der Zeile vor einer bestimmten Zeichenfolge (nicht inklusive) in der Datei über sed oder awk?

Beispiel: Ich möchte unter den Text zwischen der Zeile nach header1 und der Linie vor string_near_end_of_file (nicht inklusive) mit EXAMPLE in der Datei ersetzen ...

... 

header1 
####### 
content1 

header2 
####### 
content2 

... 

string_near_end_of_file 

... 

Vorgesehen Ergebnis:

... 

header1 
####### 
EXAMPLE 

string_near_end_of_file 

... 

Ich weiß, dass sed '/pattern1/,/.. pattern2/c\substition_string' Datei ersetzt substition_string zwischen pattern1 und pattern2 und sed -n '/pattern/{n;p}' file druckt die Linie nach der pattern passen, aber ich bin mir nicht sicher, ob ich das jetzt zusammenstellen könnte, um mein erklärtes Ziel zu erreichen.

Jede Hilfe würde sehr geschätzt werden!

Antwort

2

können Sie verwenden diese awk Befehl:

awk '/string_near_end_of_file/{p=0} !p; $1=="header1"{p=1; print "######\nEXAMPLE\n"}' file 

Ausgang:

... 

header1 
###### 
EXAMPLE 

string_near_end_of_file 

... 
+0

Habe gerade meine Frage aktualisiert, um es ein wenig klarer zu machen. – AZD

+0

Überprüfen Sie meine aktualisierte Antwort gemäß Ihrer bearbeiteten Frage. – anubhava

+0

Danke! Bevor ich Ihre Antwort akzeptiere, habe ich mich gefragt, was Sie tun würden, wenn 'header1' ein Leerzeichen enthält (so:' header 1')? Ich habe gerade festgestellt, dass ich in meiner Frage einen Fehler gemacht habe und dass ich hätte erwähnen sollen, dass die Header Leerzeichen enthalten - Entschuldigung dafür! – AZD

0

Awk Lösung (unter der Annahme, dass Header Linie immer von ####### Linie folgt):

awk -v repl="EXAMPLE" '!f && /header/{ f=1; n=NR; getline nl; r=$0 ORS nl } 
     /string_near_end_of_file/{ f=0; print r ORS repl ORS ORS $0; next } 
     f && NR>n{ next }1' file 

Der Ausgang:

... 

header1 
####### 
EXAMPLE 

string_near_end_of_file 

... 
1

GNU Sed:

sed -e '/header1/,/string_near/{/header1/{n;s/$/\nEXAMPLE\n/;n};/string_near/!d}' file

Im Bereich:

  • /header1/{n; - überspringen der header1 Linie
    • s/$/\nEXAMPLE\n/; - ersetzen Sie die ### Zeilenende mit \nEXAMPLE\n
    • n} lassen Sie die ### und Beispiel Linien allein
  • /string_near/!d; - löschen andere Linien außer string_near

sed saugt für Anforderungen Wiederholen Sie die/START /,/END/Muster innerhalb des Blocks. Sie können manchmal // verwenden, um die letzte Regex zu bezeichnen, aber alle verschachtelten Regexes beschränken ihre Verwendung in/START /,/END/Bereichen.

Beachten Sie, dass einige sed-Implementierungen Semikola erfordern, bevor geschweifte Klammern geschlossen werden.

Beachten Sie auch, dass ich Ersatz des Leitungsendes verwenden s/$/\nEXAMPLE\n/, weil es viel einfacher ist, in der Befehlszeile Inline dann ist es die sed verwenden ca oder i Befehle, die eine neue Zeile in der Befehlszeichenfolge erforderlich.

Verwandte Themen