#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,
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]
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 terminalOpé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.
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]
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,
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
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 !
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