Frage

Ich versuche, einen Regex-Ersetzungsbefehl in einem Bash-Skript zu erstellen, aber nachdem ich mit einfachen Anführungszeichen, doppelten Anführungszeichen und Escape-Zeichen herumgespielt habe, raufe ich mir die Haare.Ich verwende RegEXR, um Muster zu erstellen, und habe mir Folgendes ausgedacht:

Ich suche nach:

/\.icon-(.*) {\n\t/gm

und möchte es ersetzen durch:

if(strpos(\$embedicons,'$1') !== false) { \$svgicons .= <<<'EOD'\n\.$1 {

Dies ersetzt Folgendes:

.icon-basket-14-icon {
    background-image: url('data:image/svg+xml;charset=US-ASCII,blahblah');
    background-repeat: no-repeat;
}

mit diesem:

if(strpos($embedicons,'basket-14-icon') !== false) { $svgicons .= <<<'EOD'
.basket-14-icon {background-image: url('data:image/svg+xml;charset=US-ASCII,blahblah');
    background-repeat: no-repeat;
}

Es gelingt mir jedoch ziemlich nicht, dies innerhalb eines Bash-Skripts umzusetzen.Ich bin nicht sicher, ob es relevant ist, aber ich verwende OSX Mavericks und verwende die Terminal-App.Während die Muster in RegExr für mich Sinn ergeben, verliere ich völlig den Überblick darüber, was vor sich geht, sobald ich anfange, ihnen zu entkommen.

  1. Wie stelle ich sicher, dass die Regex global und mehrzeilig ist?
  2. Ist es besser, eine andere Option als den integrierten regulären Ausdruck zu verwenden?
  3. Gibt es eine Online-Ressource, die (Bash-)Regex beibringt, um Noobs zu vervollständigen?
  4. Gibt es ein Gruppenmuster, das alles (einschließlich Whitespace und Newlines) übereinstimmt, bis eine bestimmte Kette von Charakteren wie ein Sternchen (*)?

Offensichtlich bin ich nicht auf der Suche nach einem Almosen, da mich dieses Problem regelmäßig verfolgt ...Ich würde gerne Regex lernen und meine Probleme durch Lernen lösen und habe einige Beispiele online studiert, aber sie scheinen viel zu fortgeschritten zu sein.Vielleicht gibt es einen Online-Generator wie RegExr, der in Bash-kompatible und PHP-kompatible Versionen von Regex-Mustern übersetzt?


UPDATE/LÖSUNG:

Folgendes scheint für mich im OSX Mavericks-Terminal zu funktionieren:

sed "s|\.icon-\(.*\) {|if(strpos(\$embedicons,'\1') !== false) { \$svgicons \.= <<<'EOD' \.\1 {|g"
War es hilfreich?

Lösung

Ich würde vorschlagen, es zu verwenden sed Für diese Art von Ersatz wird diese Zeile das tun, was Sie wollen:

sed "s/^.icon-\(.*\) {$/if(strpos(\$embedicons,'\1') !== false) { \$svgicons .= <<<'EOD'\n.\1 {/"g input_file.txt

input_file.txt:

.icon-basket-14-icon {
    background-image: url('data:image/svg+xml;charset=US-ASCII,blahblah');
    background-repeat: no-repeat;
}

Ausgabe:

if(strpos($embedicons,'basket-14-icon') !== false) { $svgicons .= <<<'EOD'
.basket-14-icon {
    background-image: url('data:image/svg+xml;charset=US-ASCII,blahblah');
    background-repeat: no-repeat;
}

Mit dem -r Wenn Sie das Flag (extended regex) gesetzt haben, müssen Sie in Ihrem Beispiel nur literale Klammern und die variablen Dollarzeichen maskieren.

Zu Ihren Fragen:

  • Die g Flagge für sed macht es global.Was genau meinst du mit „mehrzeilig“?Die Ausgabe von Zeilenumbrüchen ist mit einfach, der zeilenübergreifende Abgleich ist etwas komplexer sed arbeitet Zeile für Zeile.Eine gängige Technik besteht darin, alle Zeilenumbrüche in der Datei/in den Daten durch einen Platzhalter zu ersetzen, den regulären Ausdruck/die Ersetzung unter Berücksichtigung des Platzhalters durchzuführen und dann den Platzhalter erneut durch Zeilenumbrüche zu ersetzen.
  • sed ist wahrscheinlich die beste Wahl für Dinge vom Typ Regex.Sie können die Dokumentation online finden. Diese ist ziemlich umfassend: http://www.grymoire.com/Unix/Sed.html

Für den letzten Teil verwenden (.*) wird alles erfassen, dann müssen Sie nur noch mit den Zeilenumbrüchen umgehen und sicherstellen, dass Sie Ihre Abschlusszeichenfolge ordnungsgemäß maskieren.

Testdatei:

testing data with space -
and newlines /'\ *** ends
there

Befehl (tr tauscht Zeilenumbrüche gegen Tilden und wieder zurück):

tr '\n' '~' < testfile | sed -r 's/(.*)\*\*\*.*/\1/g' | tr '~' '\n'

Ausgabe:

testing data with space -
and newlines /'\ 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top