Hast du das Bash-Handbuch gelesen? Was finden Sie unklar?
Ikarus
3
Durchsuchen Sie die bash-Manpage nach = ~
Jeff Schaller
Antworten:
46
Tatsächlich ~ist The Teil des Operators =~, der eine Übereinstimmung des Strings mit regulären Ausdrücken links und rechts vom erweiterten regulären Ausdruck ausführt.
[["string"=~ pattern ]]
Beachten Sie, dass die Zeichenfolge in Anführungszeichen gesetzt und der reguläre Ausdruck nicht in Anführungszeichen gesetzt werden sollte.
Ein ähnlicher Operator wird in der Programmiersprache Perl verwendet.
Die regulären Ausdrücke, die unter verstanden werden, bashsind die gleichen, die GNU grepmit dem -EFlag versteht, dh die erweiterte Menge regulärer Ausdrücke.
Etwas abseits des Themas, aber gut zu wissen:
Beim Abgleichen mit einem regulären Ausdruck, der Erfassungsgruppen enthält, ist der von jeder Gruppe erfasste Teil der Zeichenfolge im BASH_REMATCHArray verfügbar . Die nullte / erster Eintrag in dieser Matrix entspricht &im Ersetzungsmuster sed‚s Substitutionsbefehls (oder $&in Perl), welche das Bit des String ist, der das Muster übereinstimmt, während die Einträge mit dem Index 1 und weiter entsprechen \1, \2usw. . in einem sedErsetzungsmuster (oder $1, $2usw. in Perl), dh die von jeder Klammer angepasst Bits.
Beispiel:
string=$( date +%T )if[["$string"=~^([0-9][0-9]):([0-9][0-9]):([0-9][0-9])$ ]];then
printf 'Got %s, %s and %s\n' \
"${BASH_REMATCH[1]}""${BASH_REMATCH[2]}""${BASH_REMATCH[3]}"fi
Dies kann ausgegeben werden
Got09,19 and 14
wenn die aktuelle Zeit zufällig 09:19:14 ist.
Das REMATCHBit des BASH_REMATCHArraynamens stammt von "Regular Expression Match", dh "RE-Match".
In nicht- bashBourne-ähnlichen Shells kann auch eine expreingeschränkte Übereinstimmung mit regulären Ausdrücken verwendet werden (wobei nur grundlegende reguläre Ausdrücke verwendet werden).
Es ist dasselbe wie das, was grep -Enur auf GNU-Systemen verstanden wird und nur, wenn eine Variable ohne Anführungszeichen als Muster verwendet wird [[ $var = $pattern ]](siehe [[ 'a b' =~ a\sb ]]vs p='a\sb'; [[ 'a b' =~ $p ]]). Beachten Sie auch, dass Shell-Anführungszeichen die Bedeutung von RE-Operatoren beeinflussen und dass einige Zeichen für die Shell-Token-Erstellung in Anführungszeichen gesetzt werden müssen, die sich auf die RE-Verarbeitung auswirken können. [[ '\' =~ [\/] ]]gibt false zurück. ksh93hat noch schlimmere Probleme. Siehe zsh(oder Bash 3.1) für einen vernünftigeren Ansatz, bei dem Shell- und RE-Anführungszeichen klar voneinander getrennt sind. Die [eingebauten zshund yashhaben auch einen =~Operator.
Stéphane Chazelas
2
sehr cool off-topic! +1 (
JJoao
@ StéphaneChazelas Wie ist es "saner", dass beide von diesem Spiel in zsh ?: [[ "This is a fine mess." =~ T.........fin*es* ]]; [[ "This is a fine mess." =~ T.........fin\*es\* ]]. Oder stimmt das *auch mit einem Zitat überein? [[ "This is a fine mess." =~ "T.........fin*es*" ]].
Sorontar
Es ist vernünftiger (IMO), da es viel einfachere Regeln gibt. Shell-Quoting und RE-Escape sind klar voneinander getrennt. In [[ a =~ .* ]]oder [[ a =~ '.*' ]]oder [[ a =~ \.\* ]]wird dieselbe .*RE an den =~Operator übergeben. OTH, in bash, [[ '\' =~ [)] ]]gibt einen Fehler zurück, würden Sie wissen, ohne es zu versuchen, ob [[ '\' =~ [\)] ]]Übereinstimmungen vorliegen? Wie wäre es [[ '\' =~ [\/] ]](tut es in ksh93). Wie wäre es c='a-z'; [[ a =~ ["$c"] ]](vergleiche mit dem =Betreiber)? Siehe auch: [[ '\' =~ [^]"."] ]]was gibt false zurück ... Beachten Sie, dass Sie tun können , shopt -s compat31in bashdem bekommen zshVerhalten.
Stéphane Chazelas
zsh/ bash -o compat31‚S Verhalten [[ a =~ '.*' ]]ist auch im Einklang mit [ a '=~' '.*' ](für [Implementierungen , die Unterstützung =~) oder expr a : '.*'. OTOH, es ist nicht konsistent mit [[ a = '*' ]]vs [[ a = * ]](aber dann sind Globs Teil der Shell-Sprache, während REs nicht sind).
Stéphane Chazelas
4
Sie sollten die bash-Manpages unter dem [[ expression ]]Abschnitt lesen .
An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex(3)).
Lange Rede kurzer Sinn, =~ist ein Operator, genau wie ==und !=. Es hat nichts mit dem tatsächlichen regulären Ausdruck in der Zeichenfolge zu seiner Rechten zu tun.
Können Sie einige Beispiele finden, die den Einsatz in der Praxis demonstrieren =~...?
George Vasiliou
1
@GeorgeVasiliou Ich benutze es ziemlich oft in Skripten, die die Ausgabe eines Befehls in eine Variable setzen. Anschließend wird die Variable überprüft, um festzustellen, ob sie mit einem Zeichenfolgenmuster übereinstimmt. Dies ist zum Beispiel nützlich, wenn Sie eine Aktion basierend auf einer Fehlerausgabe dieses Befehls ausführen möchten.
Michael Martinez
@Sokel Für manche ist „RTFM“ leichter gesagt als getan. ⋯ man [[ expresssion ]]und man [[nichts zurück. help [[Gibt nützliche Informationen zurück - seit [[einem internen Bash-Befehl - aber sagt nicht, ob =~grundlegende oder erweiterte Regex-Syntax verwendet wird. ⋯ Der von Ihnen zitierte Text stammt aus der Bash- Manpage. Mir ist klar, dass Sie gesagt haben: "Lies die Manpages der Bash", aber zuerst dachte ich, Sie wollten die Manpages der Bash lesen. In jedem Fall wird man basheine riesige Datei zurückgegeben, die 4139 Zeilen (72 Seiten) lang ist. Es kann durch Drücken von gesucht werden /▒▒▒, was einen regulären Ausdruck erfordert, dessen Geschmack - wie =~- nicht spezifiziert ist.
Antworten:
Tatsächlich
~
ist The Teil des Operators=~
, der eine Übereinstimmung des Strings mit regulären Ausdrücken links und rechts vom erweiterten regulären Ausdruck ausführt.Beachten Sie, dass die Zeichenfolge in Anführungszeichen gesetzt und der reguläre Ausdruck nicht in Anführungszeichen gesetzt werden sollte.
Ein ähnlicher Operator wird in der Programmiersprache Perl verwendet.
Die regulären Ausdrücke, die unter verstanden werden,
bash
sind die gleichen, die GNUgrep
mit dem-E
Flag versteht, dh die erweiterte Menge regulärer Ausdrücke.Etwas abseits des Themas, aber gut zu wissen:
Beim Abgleichen mit einem regulären Ausdruck, der Erfassungsgruppen enthält, ist der von jeder Gruppe erfasste Teil der Zeichenfolge im
BASH_REMATCH
Array verfügbar . Die nullte / erster Eintrag in dieser Matrix entspricht&
im Ersetzungsmustersed
‚s Substitutionsbefehls (oder$&
in Perl), welche das Bit des String ist, der das Muster übereinstimmt, während die Einträge mit dem Index 1 und weiter entsprechen\1
,\2
usw. . in einemsed
Ersetzungsmuster (oder$1
,$2
usw. in Perl), dh die von jeder Klammer angepasst Bits.Beispiel:
Dies kann ausgegeben werden
wenn die aktuelle Zeit zufällig 09:19:14 ist.
Das
REMATCH
Bit desBASH_REMATCH
Arraynamens stammt von "Regular Expression Match", dh "RE-Match".In nicht-
bash
Bourne-ähnlichen Shells kann auch eineexpr
eingeschränkte Übereinstimmung mit regulären Ausdrücken verwendet werden (wobei nur grundlegende reguläre Ausdrücke verwendet werden).Ein kleines Beispiel:
quelle
grep -E
nur auf GNU-Systemen verstanden wird und nur, wenn eine Variable ohne Anführungszeichen als Muster verwendet wird[[ $var = $pattern ]]
(siehe[[ 'a b' =~ a\sb ]]
vsp='a\sb'; [[ 'a b' =~ $p ]]
). Beachten Sie auch, dass Shell-Anführungszeichen die Bedeutung von RE-Operatoren beeinflussen und dass einige Zeichen für die Shell-Token-Erstellung in Anführungszeichen gesetzt werden müssen, die sich auf die RE-Verarbeitung auswirken können.[[ '\' =~ [\/] ]]
gibt false zurück.ksh93
hat noch schlimmere Probleme. Siehezsh
(oder Bash 3.1) für einen vernünftigeren Ansatz, bei dem Shell- und RE-Anführungszeichen klar voneinander getrennt sind. Die[
eingebautenzsh
undyash
haben auch einen=~
Operator.off-topic
! +1 ([[ "This is a fine mess." =~ T.........fin*es* ]]; [[ "This is a fine mess." =~ T.........fin\*es\* ]]
. Oder stimmt das*
auch mit einem Zitat überein?[[ "This is a fine mess." =~ "T.........fin*es*" ]]
.[[ a =~ .* ]]
oder[[ a =~ '.*' ]]
oder[[ a =~ \.\* ]]
wird dieselbe.*
RE an den=~
Operator übergeben. OTH, inbash
,[[ '\' =~ [)] ]]
gibt einen Fehler zurück, würden Sie wissen, ohne es zu versuchen, ob[[ '\' =~ [\)] ]]
Übereinstimmungen vorliegen? Wie wäre es[[ '\' =~ [\/] ]]
(tut es in ksh93). Wie wäre esc='a-z'; [[ a =~ ["$c"] ]]
(vergleiche mit dem=
Betreiber)? Siehe auch:[[ '\' =~ [^]"."] ]]
was gibt false zurück ... Beachten Sie, dass Sie tun können ,shopt -s compat31
inbash
dem bekommenzsh
Verhalten.zsh
/bash -o compat31
‚S Verhalten[[ a =~ '.*' ]]
ist auch im Einklang mit[ a '=~' '.*' ]
(für[
Implementierungen , die Unterstützung=~
) oderexpr a : '.*'
. OTOH, es ist nicht konsistent mit[[ a = '*' ]]
vs[[ a = * ]]
(aber dann sind Globs Teil der Shell-Sprache, während REs nicht sind).Sie sollten die bash-Manpages unter dem
[[ expression ]]
Abschnitt lesen .An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex(3)).
Lange Rede kurzer Sinn,
=~
ist ein Operator, genau wie==
und!=
. Es hat nichts mit dem tatsächlichen regulären Ausdruck in der Zeichenfolge zu seiner Rechten zu tun.quelle
=~
...?man [[ expresssion ]]
undman [[
nichts zurück.help [[
Gibt nützliche Informationen zurück - seit[[
einem internen Bash-Befehl - aber sagt nicht, ob=~
grundlegende oder erweiterte Regex-Syntax verwendet wird. ⋯ Der von Ihnen zitierte Text stammt aus der Bash- Manpage. Mir ist klar, dass Sie gesagt haben: "Lies die Manpages der Bash", aber zuerst dachte ich, Sie wollten die Manpages der Bash lesen. In jedem Fall wirdman bash
eine riesige Datei zurückgegeben, die 4139 Zeilen (72 Seiten) lang ist. Es kann durch Drücken von gesucht werden/▒▒▒
, was einen regulären Ausdruck erfordert, dessen Geschmack - wie=~
- nicht spezifiziert ist.