J'essaie de faire correspondre un modèle avec une déclaration de casse où le motif est stocké à l'intérieur d'une variable. Voici un exemple minimal: malheureusement le "|" semble être échappé (intéressant "*" ou "?" ne sont pas). Comment puis-je obtenir cela pour travailler, c'est-à-dire correspondre à "FOO"? J'ai besoin de stocker le motif dans une variable car elle est construite de manière dynamique. Cela doit fonctionner sur une coquille compatible POSIX. P> p>
7 Réponses :
Votre modèle est en fait une liste de motifs et le séparateur | code> doit être donné littéralement. Votre seule option semble être
eval code>. Cependant, essayez d'éviter cela si vous le pouvez. P>
Je suis d'accord - vous pouvez utiliser EVAL mais c'est le chemin de la folie.
L'ensemble code> code> doit être dans la déclaration eval code> (c'est pourquoi c'est la folie); Il y a un exemple donné ici: Stackoverflow.com/a/38153401/248390
Certaines versions de sinon, j'utiliserais un outil comme AWK: P> ou plus contrariété: p> Vous pouvez l'utiliser comme ceci: P> Expr code> (par exemple GNU) permettent une correspondance de modèle avec alternance.
PATTERN="foo|bar|baz"
VALUE=oops
matches() { awk -v v="$1" -v p="$2" 'BEGIN {exit !(v~p)}'; }
if matches "$VALUE" "$PATTERN"; then
echo match
else
echo no match
fi
Cela devrait fonctionner:
PATTERN="foo|bar|baz|bla" shopt -s extglob case "foo" in @($(echo $PATTERN))) printf "matched\n" ;; *) printf "no match\n" ;; esac
Vous n'avez pas besoin du $ (echo) code> juste faire
@ ($ motif) code>
Est-ce un posixisme ou est-ce qu'un bashisme? J'ai regardé dans la page de la cendre et je n'ai pas vu cette structure, mais je n'ai pas non plus lu chaque lettre.
shopt code> n'est clairement pas POSIX ; Voir aussi page de Greycat sur le sujet .
Vous pouvez utiliser la correspondance REGEX dans BASH:
PATTERN="foo|bar|baz|bla" if [[ "foo" =~ $PATTERN ]] then printf "matched\n" elif . . . . . . elif . . . . . . else printf "no match\n" fi
"Vous ne pouvez pas y arriver d'ici"
J'aime en utilisant un étui pour le motif correspondant, mais dans cette situation, vous passez au-delà du bord de ce que Bourne Shell est bon pour. P>
là sont deux hacks pour résoudre ce problème: p>
au détriment d'une fourchette, vous pouvez utiliser EGREP P>
pattern="this|that|those" IFS="|" temp_pattern="$pattern" echo=echo for value in $temp_pattern do case foo in "$list") echo "matched" ; echo=: ; break ;; esac done $echo not matched
Cela évite la nécessité de s'échapper ou de toute autre chose:
Il est possible de faire correspondre une sous-chaîne dans une chaîne sans reproduire un sous-processus (tel que Voici une fonction de commodité: P> grep code>) à l'aide des seules méthodes compatibles POSIX de
s (1p) code>
, tel que défini dans Section 2.6.2, expansion des paramètres . PATTERN="|foo bar|baz|bla|"
case "$needle" in
xyz) echo "matched in a static part" ;;
*)
if [ -z "${PATTERN##*|${needle}|*}" ]; then
echo "$needle matched $PATTERN"
else
echo "not found"
fi
esac
Merci pour toutes les suggestions, mais je ne peux pas compter sur les outils Bash ou GNU, cela doit fonctionner sur un environnement de coquillage POSIX i>. Je voulais utiliser une construction de cas pour éviter un
si impressionnant "foo \ n" | grep -e -q "$ {motif}" 2> / dev / null; Alors ... d'autre ... FI CODE> Pour des raisons de performances (Subshell + Fourche) car je ferais un modèle de shell et je iTerai sur ce code plusieurs fois chanceux. J'étais simplement surpris que cela ne fonctionnait pas.