Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 01/10/2011, à 00:50

wolf85kunst

Tester si une variable contient une chaine [RESOLU]

Bonsoir,

Comment faire pour tester si une variable contient une chaine de caractère précise ? J'ai tenté la commande suivante :

var='chainedecar'
if [ $var="`echo $var | grep motif`" ]; then echo 'ok'; fi

Le problème est que cette commande retourne toujours "ok". Donc la condition est toujours vérifié.

Ou est mon erreur ?

Merci.

Dernière modification par wolf85kunst (Le 04/10/2011, à 21:17)


Les raisonnables ont duré, les passionnés ont vécu.
-- 10.04 Lucid Lynx --

Hors ligne

#2 Le 01/10/2011, à 01:22

Levi59

Re : Tester si une variable contient une chaine [RESOLU]

le test n'est pas bien écrit :
Il faut écrire

[ $(grep motif <<<$var) ] && echo ok

Hors ligne

#3 Le 01/10/2011, à 01:28

skingrapher

Re : Tester si une variable contient une chaine [RESOLU]

et comme ça ?

var0='chainedecar'
var1=$(echo $var0 | grep motif)
if [ $var1 != '' ]; then
  echo 'ok'
fi

Dernière modification par skingrapher (Le 01/10/2011, à 01:30)


Je suis un obsédé textuel. J'aime trop le LaTeX.

Hors ligne

#4 Le 01/10/2011, à 14:49

wolf85kunst

Re : Tester si une variable contient une chaine [RESOLU]

Bonjour,

Merci pour les réponses.

Je tombe régulièrement sur un problème du shell :
Très régulièrement, dès que je parle "condition" dans mes scripts, j'ai souvent l'erreur suivant qui s'affiche dans le terminal

Opérateur unaire attendu

Comme je sais que le shell est très pointilleux alors j'ai vérifié sans les espaces :

if [ $var1 = $var2 ]; then

Ce code renvoit l'erreur. Par contre celui-ci ne renvoit aucune erreur :

if [$var1 = $var2]; then

J'ai supprimé les espaces avant les crochets.
Pourriez-vous m'expliquer ce comportement de bash ?

Pour le reste, je rencontre des difficultés avec vos scripts.
Le script @skingrapher est plus simple mais il est plus lourd et tient en plusieurs ligne. J'ai tenté de l'adapter. Sans succès :

#!/bin/bash
var0='chainedecar'
var1=$(echo $var0 | egrep "^\.")
if [$var1 != $var0]; then
        echo 'ya pas de point'
else
        echo 'ya un point'
fi

Ce script me retourne

./tt: ligne 5 : [: « ] » manquant
ya un point

Le script de @Levi59 :

[ $(egrep -v "^\." <<<$var) ] && echo ...

erreur : "[: trop d'arguments". (avec vim : mauvaise colorisation syntaxique de "<<<")

Dernière modification par wolf85kunst (Le 01/10/2011, à 14:51)


Les raisonnables ont duré, les passionnés ont vécu.
-- 10.04 Lucid Lynx --

Hors ligne

#5 Le 01/10/2011, à 14:58

Watael

Re : Tester si une variable contient une chaine [RESOLU]

salut

en sh

echo "$var" | grep motif && echo ok || echo ko

en bash

motif="regex"
[[ $var =~ $motif ]] && echo ok || echo ko

Dernière modification par Watael (Le 01/10/2011, à 14:59)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#6 Le 01/10/2011, à 16:53

pingouinux

Re : Tester si une variable contient une chaine [RESOLU]

Bonjour,

wolf85kunst #4 a écrit :

Opérateur unaire attendu

Comme je sais que le shell est très pointilleux alors j'ai vérifié sans les espaces :

if [ $var1 = $var2 ]; then

Ce code renvoit l'erreur

Il est préférable d'écrire :

if [ "$var1" = "$var2" ]; then

au cas où l'une des chaînes serait vide.
Cordialement

Hors ligne

#7 Le 01/10/2011, à 17:15

Bousky

Re : Tester si une variable contient une chaine [RESOLU]

La meilleure méthode est celle de Watael (même s'il n'est pas nécessaire de passer par une variable pour le motif), mais à nuancer avec la remarque de pingouinux :

 if [[ "$var" =~ "regex" ]]

Il faut toujours placer les variables dont on a pas le contrôle absolu entre guillemets doubles, sinon il suffit pour que la variable soit vide, non définie ou qu'elle contienne un espace pour que ça plante.


Linux qui plante complètement ? Plus rien ne répond ? On peut toujours le redémarrer proprement :
Alt + SysRq + REISUB (Retourne En Islande Sur Un Bateau !)

Hors ligne

#8 Le 01/10/2011, à 17:15

aduxas

Re : Tester si une variable contient une chaine [RESOLU]

wolf85kunst a écrit :

Je tombe régulièrement sur un problème du shell :
Très régulièrement, dès que je parle "condition" dans mes scripts, j'ai souvent l'erreur suivant qui s'affiche dans le terminal

Opérateur unaire attendu

S'il y a un blanc d'un seul côté du signe "=", il est simplement collé au contenu de la variable du côté où l'espace manque, et il disparaît comme opérateur dans ton expression.  Tu ne teste plus une égalité; tu a simplement deux mots, dont l'un se termine ou l'autre commence par "=".  Aussi, si l'un des variables est la chaîne vide, il manque un member dans ton test et t'auras la même erreur.

wolf85kunst a écrit :
if [ $var1 = $var2 ]; then

Ce code renvoit l'erreur. Par contre celui-ci ne renvoit aucune erreur :

if [$var1 = $var2]; then

J'ai supprimé les espaces avant les crochets.
Pourriez-vous m'expliquer ce comportement de bash ?

Ce n'est pas plutôt à l'envers?  La première expression est la bonne.  Mettez toujours des espaces autour de l'expression à l'intérieur des crochets.  N'oublie pas que

[ expression ]

est équivalent à

test expression

et retourne 0 si le test est vrai et 1 sinon.

Hors ligne

#9 Le 01/10/2011, à 17:27

Bousky

Re : Tester si une variable contient une chaine [RESOLU]

[$var1 = $var2]

ne renverra pas d'erreur si les deux variables sont vides. Pour que ça marche, il faut mettre des espaces partout et des guillemets autour de chaque variable.


Linux qui plante complètement ? Plus rien ne répond ? On peut toujours le redémarrer proprement :
Alt + SysRq + REISUB (Retourne En Islande Sur Un Bateau !)

Hors ligne

#10 Le 01/10/2011, à 17:59

Levi59

Re : Tester si une variable contient une chaine [RESOLU]

Bousky a écrit :
 if [[ "$var" =~ "regex" ]]

Il faut toujours placer les variables dont on a pas le contrôle absolu entre guillemets doubles, sinon il suffit pour que la variable soit vide, non définie ou qu'elle contienne un espace pour que ça plante.

Ce n'est pas nécessaire lorsque qu'on utilise les doubles crochets de test. il considère automatiquement les ensembles avant et après le test (-gt, -le...) comme étant un seul bloc.

De plus j'ai fait une petite erreur pour mon précédent post. Il faut utiliser les crochets doubles:

[[ $(grep "motif" <<<$var) ]] && echo ok

Cette commande fonctionne parfaitement en bash. (Et "<<<" evite la pipe et l'appelle à echo en redirigeant le contenu de var dans grep. c'est l’équivalent de "--echo $var | grep "motif"--")
exemple:

crunchbang:~ a=( 1 "111" "123" "124" )
crunchbang:~ [ $(grep "2" <<<${a[@]}) ] && echo ok
bash: [: trop d'arguments
crunchbang:~ [[ $(grep "2" <<<${a[@]}) ]] && echo ok
ok

Dernière modification par Levi59 (Le 01/10/2011, à 18:16)

Hors ligne

#11 Le 01/10/2011, à 19:25

Watael

Re : Tester si une variable contient une chaine [RESOLU]

bash: [: trop d'arguments

Le résultat des substitutions de commandes aussi doit être entre guillemets.
Le test est vraiment superflu, que ce soit avec un ou deux crochets.
S'il faut utiliser grep, il vaut mieux simplement se servir de son code de retour.
On peut rendre grep silencieux (-q) pour qu'il n'affiche pas les résultats trouvés.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#12 Le 01/10/2011, à 23:44

Postmortem

Re : Tester si une variable contient une chaine [RESOLU]

Salut,

Bousky a écrit :

La meilleure méthode est celle de Watael (même s'il n'est pas nécessaire de passer par une variable pour le motif), mais à nuancer avec la remarque de pingouinux :

 if [[ "$var" =~ "regex" ]]

Il faut toujours placer les variables dont on a pas le contrôle absolu entre guillemets doubles, sinon il suffit pour que la variable soit vide, non définie ou qu'elle contienne un espace pour que ça plante.

Petite précision, [[ "$var" =~ "regex" ]] ne fonctionne pas ; il faut enlever les guillemets pour que regex soit considérée comme... Une regex ! Si on la met entre doubles ou simples quote, c'est considéré comme une chaîne de caractères.

$ var=toto
$ [[ "$var" =~ "t.*" ]] && echo OK || echo KO
KO
$ [[ "$var" =~ t.* ]] && echo OK || echo KO
OK
Watael a écrit :

Le test est vraiment superflu, que ce soit avec un ou deux crochets.
S'il faut utiliser grep, il vaut mieux simplement se servir de son code de retour.
On peut rendre grep silencieux (-q) pour qu'il n'affiche pas les résultats trouvés

+1 ; ceci suffit, pas besoin de test (et la regex dans ce cas va entre simples ou doubles quotes) :

grep -q 'regex' <<< "$var" && echo OK

Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#13 Le 04/10/2011, à 21:16

wolf85kunst

Re : Tester si une variable contient une chaine [RESOLU]

Merci à vous tous pour vos réponses. Ce sujet est résolu.


Les raisonnables ont duré, les passionnés ont vécu.
-- 10.04 Lucid Lynx --

Hors ligne

#14 Le 19/03/2018, à 18:03

Zer00CooL

Re : Tester si une variable contient une chaine [RESOLU]

Bonjour, je déterre ce post qui m'a aidé à avancer. Grâce à cette lecture, j'ai pu trouver une solution en Bash.
Par contre, en Shell, je trouve cela limité, car, je dois tester 33 valeurs, une à une. A chaque fois, la chaine de caractères sera réécrite dans le terminal.
Est t'il possible d'éviter l'écriture de la chaine de caractère complète, en Shell, et, de tester tout de même la présence d'une chaîne partielle ?

#sh

echo "$pays" | grep TP_Allemagne && echo Allemagne || echo ko
echo "$pays" | grep TP_Angleterre && echo Angleterre || echo ko

#bash OK

All="TP_Allemagne"
[[ $pays =~ $All ]] && echo Allemagne || echo ko Allemagne
Ang="TP_Angleterre"
[[ $pays =~ $Ang ]] && echo Angleterre || echo ko Angleterre

#bash OK

[[ $(grep "TP_Allemagne" <<<$pays) ]] && echo Allemagne
[[ $(grep "TP_Angleterre" <<<$pays) ]] && echo Angleterre

Dernière modification par Zer00CooL (Le 19/03/2018, à 18:04)

Hors ligne

#15 Le 19/03/2018, à 18:33

Watael

Re : Tester si une variable contient une chaine [RESOLU]

la dernière proposition* est affreuse.

*je ne dis pas solution parce que c'est trop horrible !
wink


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#16 Le 19/03/2018, à 18:56

MicP

Re : Tester si une variable contient une chaine [RESOLU]

Bonjour

Je ne sais pas comment se présentent les listes à comparer,
mais peut-être comme ça :

michel@debg53sw:~$ chaineAtester="BlablipBlaTP_AngleterreBla bloBlaTP_PoldévieBlaBla BlaTP_Allemagneblurg"
michel@debg53sw:~$ listePays="Allemagne Angleterre Moldavie Andorre"
michel@debg53sw:~$ for pays in $listePays; do [[ "$chaineAtester" =~ TP_$pays ]] && echo $pays; done
Allemagne
Angleterre
michel@debg53sw:~$ 

Dernière modification par MicP (Le 19/03/2018, à 19:04)

Hors ligne