2017-01-03 8 views
0

Aktualisierung der Frage Muster entsprechen:sed das zweite Auftreten des

Ich habe eine Datei, die unten in einem der beiden Formate Codeblock enthält erwähnt:

1.

$Subj .= "HAD PROBLEMS"; 

    if ($To) { 
     $Cc = "abc\@example.com"; 
    } 
    else { 
     $Cc = "abc\@example.com"; 
    } 

2.

$Subj .= "HAD PROBLEMS"; 

    if ($To) { $Cc = "abc\@example.com"; } else { $Cc = "abc\@example.com"; } 

ich brauche die E-Mail-ID in $ Cc Variable (2. Vorkommen) mit einem neuen em ersetzen ail ID für beide Formate.

Ich habe den folgenden sed Befehl, dies zu tun.

sed '\|HAD PROBLEMS|,/}/ s/$Cc = \(\"[A-Za-z0-9]*\)\(.*\)\([A-Za-z0-9]*\)\@example.com\"/\$Cc = "new email\\@example.com"/' test.txt 

Dieser Befehl wird die E-Mail-ID nur für die $Cc Variable in dem, wenn {} Block (erstes Auftreten von $Cc), da meinem Ende Einstimmungsmuster ist ein ‚}‘ ersetzen. Ich möchte E-Mail-ID in der zweiten $Cc auch ersetzen. Wie passe ich beim 2. Auftreten von '}'?

Die unten genannte Lösung funktioniert für das erste Format. Aber ich brauche eine generische Lösung, die für beide Formate funktioniert. Kann mir bitte jemand helfen.

Ich hoffe, die Beschreibung ist klar.

+0

Ihre Eingabe ist nicht klar, beheben Sie die Syntax Probleme im Skript mit einer richtigen erwarteten Ausgabe. – Inian

+0

Warum setzen Sie $ Cc unabhängig von $ To auf denselben Wert? Ist das ein Tippfehler? – codeforester

+2

@Inian, Ihr sed-Skript ersetzt tatsächlich beide Instanzen, aber das ist nicht das, wonach das OP sucht. Er will nur die * zweite * Instanz, die in einem 'else'-Block eines 'if' erscheint, der nach dem Wort' HAS PROBLEMS' steht. Während dies sehr wohl etwas sein könnte, was in sed ausgedrückt werden könnte, würde es wahrscheinlich erfordern, dass seds Speicherplatz und ein Schnipsel wie 'x; s/[az] + \\ @ [az .-] +/new @ Beispiel verwendet wird. com/2; p', sobald Sie herausgefunden haben, wie Sie nur den wichtigen Teil der Datei in den Speicherplatz von sed bringen. Zu spät in der Nacht, um das herauszufinden, also ... awk zur Rettung! – ghoti

Antwort

0

Scheint mir, dass awk eine klarere Sprache wäre, um dieses Problem auszudrücken.

awk '/HAD PROBLEMS/{x=1} /}/{x++} x==2&&/\$Cc =/{sub(/[a-z]+\\@[a-z.-]+/,"[email protected]"); unset x} 1' input.txt 

Oder gestaffelt ist zur leichteren Kommentierung:

# search for your start pattern, set a counter. 
/HAD PROBLEMS/ {x=1}   

# increment the counter at the first close-squigly. 
/}/ {x++}     

# If we've done our increment and we're on the right line, 
x==2 && /\$Cc =/ {   
    # substitute the existing address with a new one, 
    sub(/[a-z]+\\@[a-z.-]+/,"[email protected]"); 
    # and reset our counter. 
    unset x 
} 

# Print the current line. 
1       
+0

Das funktioniert für mich. Aber ich muss vor Ort suchen und ersetzen. Ich habe awk Version 3.1.5 ausgeführt und ich kann inplace mit dem obigen Befehl nicht tun. Gibt es eine sed Version der obigen Antwort? Das wäre sehr hilfreich. – DND

+0

Sed inplace kopiert die Datei einfach in eine temporäre Datei und benennt sie um. Sie können dies selbst mit einem Shell-Wrapper machen. 'awk '/ HAD PR ...' file.txt> Ausgabe. $$ && mv Ausgabe. $$ file.txt' – ghoti

+0

Es funktioniert. Brauche noch eine Hilfe von dir. Ich habe ähnlichen Code in einer Zeile. Aber die gleiche Lösung funktioniert nicht. Sucht es nur in einer neuen Zeile nach '}'? Kannst du damit helfen? $ Subj. = "HAT PROBLEME"; if ($ To) {$ Cc = "xyz \ @ abc.com"; } else {$ Cc = "xyz \ @ abc.com"; } – DND

Verwandte Themen