web-dev-qa-db-fra.com

Comment comparer les chaînes dans Bash

Comment comparer une variable à une chaîne (et faire quelque chose si elles correspondent)?

863
Erik Sapir

Utilisation de variables dans les instructions if

if [ "$x" = "valid" ]; then
  echo "x has the value 'valid'"
fi

Si vous voulez faire quelque chose quand ils ne correspondent pas, remplacez = par !=. Vous pouvez en savoir plus sur opérations sur les chaînes de caractères et opérations arithmétiques dans leurs documentations respectives.

Pourquoi utilisons-nous des guillemets autour de $x?

Vous voulez les guillemets autour de $x, car s'il est vide, votre script bash rencontre une erreur de syntaxe, comme indiqué ci-dessous:

if [ = "valid" ]; then

Utilisation non standard de l'opérateur ==

Notez que bash autorise == à être utilisé pour l'égalité avec [, mais ceci n'est pas standard .

Utilisez soit le premier cas où les guillemets autour de $x sont optionnels:

if [[ "$x" == "valid" ]]; then

ou utilisez le second cas:

if [ "$x" = "valid" ]; then
1241
John Feminella

Ou, si vous n'avez pas besoin de la clause else:

[ "$x" == "valid" ] && echo "x has the value 'valid'"
131
Marko
a="abc"
b="def"

# Equality Comparison
if [ "$a" == "$b" ]; then
    echo "Strings match"
else
    echo "Strings don't match"
fi

# Lexicographic (greater than, less than) comparison.
if [ "$a" \< "$b" ]; then
    echo "$a is lexicographically smaller then $b"
Elif [ "$a" \> "$b" ]; then
    echo "$b is lexicographically smaller than $a"
else
    echo "Strings are equal"
fi

Notes:

  1. Les espaces entre if et [ et ] sont importants
  2. > et < sont des opérateurs de redirection, vous devez donc y échapper avec \> et \< pour les chaînes.
69
Guru

Pour comparer des chaînes avec des caractères génériques, utilisez

if [[ "$stringA" == *$stringB* ]]; then
  # Do something here
else
  # Do Something here
fi
59
Jeffrey L. Roberts

Je ne suis pas d'accord avec l'un des commentaires sur un point:

[ "$x" == "valid" ] && echo "valid" || echo "invalid"

Non, ce n'est pas un oneliner fou

C'est juste que ça ressemble à un, hmm, le non-initié ...

Il utilise des modèles communs comme langage, d’une certaine manière;

Et après avoir appris la langue.

En fait, c'est agréable à lire

C'est une simple expression logique, avec une partie spéciale: l'évaluation paresseuse des opérateurs logiques.

[ "$x" == "valid" ] && echo "valid" || echo "invalid"

Chaque partie est une expression logique. le premier peut être vrai ou faux, les deux autres sont toujours vrais.

(
[ "$x" == "valid" ] 
&&
echo "valid"
)
||
echo "invalid"

Maintenant, quand il est évalué, le premier est vérifié. S'il est faux, alors le second opérande de la logique et && après cela n'est pas pertinent. La première n'est pas vraie, donc elle ne peut pas être la première et la seconde aussi, de toute façon.
Maintenant, dans ce cas, se trouve le premier côté de la logique ou || false , mais cela pourrait être vrai si l’autre côté - la troisième partie - est vrai.

Donc, la troisième partie sera évaluée - principalement l’écriture du message en tant qu’effet secondaire. (Il a pour résultat 0 pour true, que nous n'utilisons pas ici)

Les autres cas sont similaires, mais plus simples - et - je le promets! sont - peuvent être - faciles à lire!
(Je n'en ai pas, mais je pense qu'être un ancien combattant d'UNIX avec une barbe grise m'aidera beaucoup avec ça.)

33
Volker Siegel

vous pouvez également utiliser le cas d'utilisation/esac

case "$string" in
 "$pattern" ) echo "found";;
esac
20
ghostdog74

le script suivant lit un fichier nommé "testonthis" ligne par ligne, puis compare chaque ligne avec une chaîne simple, une chaîne avec des caractères spéciaux et une expression régulière si elle ne correspond pas. Le script imprimera la ligne o/w pas.

l'espace dans bash est tellement important. afin de suivre

[ "$LINE" != "table_name" ] 

mais ne suivront pas:

["$LINE" != "table_name"] 

alors s'il vous plaît utiliser tel quel:

cat testonthis | while read LINE
do
if [ "$LINE" != "table_name" ] && [ "$LINE" != "--------------------------------" ] && [[ "$LINE" =~ [^[:space:]] ]] && [[ "$LINE" != SQL* ]]; then
echo $LINE
fi
done
14
Harshil

J'utiliserais probablement des correspondances d'expressions rationnelles si l'entrée ne comporte que quelques entrées valides. Par exemple. seules les actions "start" et "stop" sont valides.

if [[ "${ACTION,,}" =~ ^(start|stop)$ ]]; then
  echo "valid action"
fi

Notez que je mets la variable $ACTION en minuscule en utilisant la double virgule. Notez également que cela ne fonctionnera pas avec des versions trop anciennes de bash.

11
steviethecat

Bash4 + exemples. Remarque: ne pas utiliser de guillemets causera des problèmes lorsque les mots contiennent des espaces, etc. Toujours citer entre guillemets dans IMO.

Voici quelques exemples BASH4 +:

Exemple 1, recherchez "oui" dans la chaîne (insensible à la casse):

    if [[ "${str,,}" == *"yes"* ]] ;then

Exemple 2, recherchez "oui" dans la chaîne (insensible à la casse):

    if [[ "$(echo "$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then

Exemple 3, recherchez "oui" dans la chaîne (sensible à la casse):

     if [[ "${str}" == *"yes"* ]] ;then

Exemple 4, recherchez 'oui' dans la chaîne (sensible à la casse):

     if [[ "${str}" =~ "yes" ]] ;then

Exemple 5, correspondance exacte (sensible à la casse):

     if [[ "${str}" == "yes" ]] ;then

Exemple 6, correspondance exacte (insensible à la casse):

     if [[ "${str,,}" == "yes" ]] ;then

Exemple 7, correspondance exacte:

     if [ "$a" = "$b" ] ;then

prendre plaisir.

8
Mike Q

Je l'ai fait de cette manière compatible avec bash, dash (sh):

testOutput="my test"
pattern="my"

case $testOutput in (*"$pattern"*)
    echo "if there is a match"
    exit 1
    ;;
(*)
   ! echo there is no coincidence!
;;esac
1
shades3002