Ich finde das oft in Skripten (und ich muss zugeben, ich schreibe es selbst):
a=$(echo "$x" | sed "s/foo/bar/")
oder
if echo "$x" | grep -q foo
then
...
fi
Betrachten Sie "foo", um einige Regex-Sachen aufzunehmen.
Ich bin der Meinung, dass es einen besseren Weg geben sollte - und höchstwahrscheinlich auch gibt -, der nicht zwei Befehle und eine Pipe beinhaltet, sondern das Ding in einen kompakteren Ausdruck einwickelt.
Ich kann es einfach nicht finden. Irgendjemand?
$()
Ersetzen von Befehlen eher Backticks als Backticks.a="$(echo "$x" | sed "s/foo/bar/")"
undif echo "$x" | grep foo; …
.Antworten:
Wenn Sie nicht von einer bestimmten Shell ausgehen, gibt es keinen besseren Weg, dies zu tun als "Pipe Echo to Tool" (oder nur ein "Tool" selbst wie expr ). Mit der traditionellen Bourne-Shell und / oder der POSIX-Shell können Sie sich wirklich auf alles verlassen . Wenn Sie andere Muscheln in Betracht ziehen, gibt es einige andere integrierte Möglichkeiten.
ksh hat
?(pattern-list)
,*(pattern-list)
,{n}(pattern-list)
,{n,m}(pattern-list)
,@(pattern-list)
,!(pattern-list)
;%P
printf- Bezeichner zum Konvertieren eines erweiterten regulären Ausdrucks in ein Muster (und%R
zum Erweitern eines erweiterten regulären Ausdrucks in ein Muster);expr == pattern
Zustand in[[ expr ]]
Tests;${param/pattern/replacement}
Parametererweiterung.Bash hat
extglob
Option, die meisten zusätzlichen Muster von ksh (no{n}
und{n,m}
) zu aktivieren ;expr == pattern
Zustand (in[[ expr ]]
Tests);${param/pattern/replacement}
Parametererweiterung;expr =~ extregexp
Bedingung (in[[ expr ]]
Tests), die mit erweiterten regulären Ausdrücken übereinstimmen kannBASH_REMATCH
Parameter könnten Ersetzungen im sed- Stil durchgeführt werden.zsh hat
EXTENDED_GLOB
Option;KSH_GLOB
Option;expr == pattern
Zustand (in[[ expr ]]
Tests);${pattern/pattern/replacement}
Parametererweiterung;expr =~ extregexp
Bedingung (in[[ expr ]]
Tests), die mit erweiterten regulären Ausdrücken übereinstimmen kann,MATCH
Parameter und demmatch
Parameter (oderBASH_REMATCH
mit demBASH_REMATCH
Optionssatz) könnten Ersetzungen im sed- Stil durchgeführt werden.zsh/pcre
Modul, das bietetpcre_compile
,pcre_study
undpcre_match
Befehle und die-pcre-match
Testbedingung (in[[ expr ]]
Tests);zsh/regex
Modul, das die-regex-match
Testbedingung bietet (in[[ expr ]]
Tests).quelle
Gehen Sie wie folgt vor, um die sed-Leitung zu ersetzen
${a/foo/bar}
oder${a//foo/bar}
In der ersten Form wird nur die erste Instanz ersetzt. Das zweite Formular ist ein globales Suchen und Ersetzen.
In Ihrem Fall wäre es
Anstatt:
Erwägen Sie die Verwendung von:
Wo
foo
ist ein regulärer Ausdruck.quelle
if [ $x =~ foo ]
gibt hier eine Fehlermeldung aus.if [[ $x =~ foo ]]
funktioniert jedoch hervorragend. Vielen Dank!=~
erfordert bash> = 3 iirc.${a##foo}
und${a%%bar}
.=~
verwendet reguläre Ausdrücke. Dies gilt zum Beispiel:[[ "abcdddde" =~ ^a.*d+.g* ]]
(das sind zum Beispiel null oder mehr gs anstelle von g-Platzhaltern).Eine gute posix-kompatible Methode zum Testen, ob eine Variable ein Muster enthält, ist:
Die Syntax der Parametererweiterung lautet:
wobei
pattern
ein Shell - Muster .quelle