Antworten:
Ja, sie sind (fast) gleichwertig.
In einem [ … ]
Konstrukt:
Der =
Operator (oder auch die Nicht-Posix-Option von ==
) testet den String-Abgleich, nicht den Muster-Abgleich.
Innerhalb eines [[ ]]
Konstrukts (von man bash):
Wenn die Operatoren == und! = Verwendet werden, wird die Zeichenfolge rechts vom Operator als Muster betrachtet und gemäß den im Folgenden unter Mustervergleich beschriebenen Regeln abgeglichen . Wenn die Shell- Option "nocasematch" aktiviert ist, wird die Übereinstimmung ohne Berücksichtigung der Buchstaben ausgeführt. Der Rückgabewert ist 0, wenn der String mit dem Muster übereinstimmt (==) oder nicht übereinstimmt (! =), Andernfalls 1. Jeder Teil des Musters kann in Anführungszeichen gesetzt werden, um die Übereinstimmung als Zeichenfolge zu erzwingen.
Innerhalb eines case
Konstrukts (von man bash, bearbeitet und Hervorhebung von mir):
case word in [[(] pattern [| pattern] ...) list ;; ] ... esac
... versucht es gegen jedes Muster wiederum zu entsprechen, die gleiche Matching Regeln wie für Pfadnamenerweiterung (siehe Pathname Expansion weiter unten). … Jedes untersuchte Muster wird durch Tildeerweiterung, Parameter- und Variablenerweiterung, arithmetische Substitution, Befehlssubstitution und Prozesssubstitution erweitert. Wenn die Shell- Option "nocasematch" aktiviert ist, wird die Übereinstimmung ohne Berücksichtigung der Buchstaben ausgeführt.
Beide Pattern Matching
und Pathname Expansion
werden im Bash-Handbuch verwendet, um dasselbe zu bedeuten.
Der einzige Unterschied, den ich im Handbuch sehen kann, ist:
`[[ … ]]` case
tilde expansion tilde expansion
parameter and variable expansion parameter and variable expansion
arithmetic expansion arithmetic substitution
command substitution command substitution
process substitution process substitution
quote removal
Dies quote removal
ist für das case-Konstrukt nicht explizit aufgeführt.
Was genau dazu passt (für die [[ … ]]
):
Jeder Teil des Musters kann in Anführungszeichen gesetzt werden, um die Übereinstimmung als Zeichenfolge zu erzwingen.
Verwenden Sie dies, um diesen letzten Punkt zu testen (jetzt ist die Variable kein Muster):
case "$1" in
"$pattern") echo case match
esac
Implizit extglob
:
Seit Version 4.3 von Bash
Wenn die Operatoren '==' und '! =' Verwendet werden, wird die Zeichenfolge rechts neben dem Operator als Muster betrachtet und gemäß den im Abschnitt Mustervergleich beschriebenen Regeln abgeglichen, als ob die Option extglob shell aktiviert wäre .
Das bedeutet, dass ein mit der Option extglob
unset verwendetes Muster in einer case-Anweisung und in einem [[
Konstrukt nach der bash-Version 4.3 anders funktioniert .
Implizit |
:
Die Syntax für case lautet:
case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac
Dies bedeutet, dass mehrere Muster durch ein |
(ODER) getrennt sein können.
So was:
shopt -s extglob; p1="+([0-9])"; p2="+([abcde])"
case "$1" in
$p1|$p2) echo "or case match" ; ;;
esac
Womit entweder nur eine Folge von Zahlen oder nur Buchstaben in abcde
, wie 1234
oder aabee
, aber nicht 12a
oder übereinstimmen b23
.
A [[
wird gleichwertig funktionieren, wenn Regex (siehe var p3) verwendet wird:
#!/bin/bash
shopt -s extglob ### Use extended globbing.
shopt -s globasciiranges ### The range [a-z] will expand to [abcdefghijklmnopqrstuvwxyz].
pattern="+([0-9])"
p1="+([0-9])"
p2="+([a-z])"
p3="^([0-9]+|[a-z]+)$"
case "$1" in
$pattern) echo case1 match ; ;&
$p1|$p2) echo case2 match ; ;;
esac
[[ "$1" == $pattern ]] && echo if1 match
[[ "$1" =~ $p3 ]] && echo if2 match
shopt
Einstellungen und Werten in$1
oderpattern
oder$?
danach. Der einzige Unterschied besteht darin, dass$1
die Ausgabe beim Ausführen unter nicht erweitert wirdxtrace
.