Ich habe dieses Beispiel gesehen:
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//[0-9]/}
Welches folgt dieser Syntax: ${variable//pattern/replacement}
Leider pattern
scheint das Feld keine vollständige Regex-Syntax zu unterstützen (wenn ich es verwende .
oder \s
zum Beispiel versuche, mit den Literalzeichen übereinzustimmen).
Wie kann ich eine Zeichenfolge mit vollständiger Regex-Syntax suchen / ersetzen?
\s
ist nicht Teil der von POSIX definierten Standardsyntax für reguläre Ausdrücke (weder BRE noch ERE). Es ist eine PCRE-Erweiterung und meistens nicht über die Shell erhältlich.[[:space:]]
ist das universellere Äquivalent.\s
kann[[:space:]]
übrigens.
durch ersetzt werden?
, und extglob-Erweiterungen der Baseline-Shell-Mustersprache können für Dinge wie optionale Untergruppen, wiederholte Gruppen und dergleichen verwendet werden.Antworten:
Verwenden Sie sed :
Beachten Sie, dass die nachfolgenden in
-e
der richtigen Reihenfolge verarbeitet werden. Dasg
Flag für den Ausdruck stimmt auch mit allen Vorkommen in der Eingabe überein.Mit dieser Methode können Sie auch Ihr Lieblingswerkzeug auswählen, z. B. Perl, Awk, z.
Auf diese Weise können Sie möglicherweise mehr kreative Übereinstimmungen erstellen ... Im obigen Ausschnitt wird beispielsweise die numerische Ersetzung nur verwendet, wenn der erste Ausdruck eine Übereinstimmung aufweist (aufgrund von Faulheit)
and
Auswertung). Und natürlich haben Sie die volle Sprachunterstützung von Perl, um Ihre Gebote abzugeben ...quelle
sed
oder anderer externer Tools ist aufgrund der Prozessinitialisierungszeit teuer. Ich habe insbesondere nach einer All-Bash-Lösung gesucht, da ich festgestellt habe, dass die Verwendung von Bash-Substitutionen mehr als dreimal schneller ist als das Aufrufensed
jedes Elements in meiner Schleife.Dies kann tatsächlich in reiner Bash erfolgen:
... ergibt ...
quelle
=~
ist der Schlüssel. Aber etwas klobig angesichts der Neuzuweisung in der Schleife. @jheddings Lösung 2 Jahre zuvor ist eine weitere gute Option - Sed oder Perl anrufen).sed
oderperl
ist sinnvoll, wenn mit jedem Aufruf mehr als eine einzelne Eingabezeile verarbeitet wird. Das Aufrufen eines solchen Tools im Inneren einer Schleife ist tollkühn, im Gegensatz zur Verwendung einer Schleife zur Verarbeitung ihres Ausgabestreams.$match
statt$BASH_REMATCH
. (Sie können es wie Bash mit verhaltensetopt bash_rematch
.)Diese Beispiele funktionieren auch in Bash, ohne dass sed verwendet werden muss:
Sie können auch die Ausdrücke der Zeichenklassenklammer verwenden
Ausgabe
Was @Lanaru jedoch wissen wollte, wenn ich die Frage richtig verstehe, ist, warum die "Voll" - oder PCRE-Erweiterungen
\s\S\w\W\d\D
usw. nicht so funktionieren, wie sie in PHP Ruby Python usw. unterstützt werden. Diese Erweiterungen stammen aus Perl-kompatiblen regulären Ausdrücken (PCRE) und ist möglicherweise nicht mit anderen Formen von Shell-basierten regulären Ausdrücken kompatibel.Diese funktionieren nicht:
Ausgabe mit allen wörtlichen "d" -Zeichen entfernt
Das Folgende funktioniert jedoch wie erwartet
Ausgabe
Ich hoffe, das klärt die Dinge ein bisschen mehr, aber wenn Sie noch nicht verwirrt sind, warum versuchen Sie dies nicht unter Mac OS X, für das das Flag REG_ENHANCED aktiviert ist:
Bei den meisten Varianten von * nix wird nur die folgende Ausgabe angezeigt:
nJoy!
quelle
${foo//$bar/$baz}
ist keine POSIX.2 BRE- oder ERE-Syntax - es ist ein Mustervergleich im fnmatch () - Stil.${hello//[[:digit:]]/}
Werke, wenn wir nur zum Ausfiltern von Ziffern mit vorangestelltem Buchstaben wollteno
,${hello//o[[:digit:]]*}
hätte ein ganz anderes Verhalten als die erwarteten (da in fnmatch Mustern,*
paßt auf alle Zeichen, anstatt die unmittelbar vor Punkt modifiziert werden 0 oder mehr).[0-9]
oder[[:digit:]]
Wenn Sie wiederholt Anrufe tätigen und sich um die Leistung kümmern, zeigt dieser Test, dass die BASH-Methode ~ 15x schneller ist als das Verzweigen in sed und wahrscheinlich jeder andere externe Prozess.
quelle
Verwenden Sie
[[:digit:]]
(beachten Sie die doppelten Klammern) als Muster:Ich wollte nur die Antworten zusammenfassen (insbesondere @ nickl-s https://stackoverflow.com/a/22261334/2916086 ).
quelle