Je voudrais dire si une chaîne $string
correspondrait à un modèle glob $pattern
. $string
peut ou peut ne pas être le nom d'un fichier existant. Comment puis-je faire ceci?
Supposons les formats suivants pour mes chaînes d'entrée:
string="/foo/bar"
pattern1="/foo/*"
pattern2="/foo/{bar,baz}"
Je voudrais trouver un idiome bash qui détermine si $string
serait compensée par $pattern1
, $pattern2
ou tout autre motif glob arbitraire. Voici ce que j'ai essayé jusqu'à présent:
[[ "$string" = $pattern ]]
Cela fonctionne presque, sauf qu'il
$pattern
est interprété comme un modèle de chaîne et non comme un modèle global.[ "$string" = $pattern ]
Le problème avec cette approche est qu'elle
$pattern
est étendue et que la comparaison des chaînes est effectuée entre$string
et l'expansion de$pattern
.[[ "$(find $pattern -print0 -maxdepth 0 2>/dev/null)" =~ "$string" ]]
Celui-ci fonctionne, mais uniquement s'il
$string
contient un fichier qui existe.[[ $string =~ $pattern ]]
Cela ne fonctionne pas car l'
=~
opérateur fait$pattern
en sorte qu'il soit interprété comme une expression régulière étendue et non comme un modèle glob ou générique.
ls /foo/*
maintenant vous pouvez égaler dans un
foo/{bar,baz}
s'agit en fait d'une extension d'accolade (pas d'une extension de paramètre) alors que foo/*
c'est une extension de nom de chemin. $string
est l'expansion des paramètres. Tout cela se fait à différents moments et par différents mécanismes.
case
instruction exécute l'extension de nom de chemin ("globbing") conformément au manuel de Bash.
{bar,baz}
n'est pas un modèle. C'est l'expansion des paramètres. Une différence subtile mais critique en cela{bar,baz}
est développée très tôt dans de multiples arguments,bar
etbaz
.