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 27/02/2009, à 12:24

Flo45

Bash : test d'un caractere

Bonjour,

Voila je fais un peu de scripting en bash, et je suis confronter à un probleme sur le test d'un caractere, je m'explique :

j'ai une variable X, qui contient un caractere (numérique ou alphanumérique).
Et donc j'aimerais tester cette variable qui contient le caractere et si la variable contient un numérique, on fait le traitement Y mais si la variable contient de l'alphanumérique on fait le traitement Z.

Voila j'espere que j'ai été assez clair hmm

Merci d'avance pour votre aide smile

#2 Le 27/02/2009, à 12:45

alexduf

Re : Bash : test d'un caractere

Bonjour,

Un chouilla de google t'aurais rapidement amené ici :  http://www.commentcamarche.net/faq/sujet-4605-shell-tester-une-variable-numerique

Bonne lecture ;-)

Hors ligne

#3 Le 27/02/2009, à 14:33

Totor

Re : Bash : test d'un caractere

alexduf a écrit :

http://www.commentcamarche.net/faq/sujet-4605-shell-tester-une-variable-numerique

Il existe aussi une solution Bash native (puisqu'il s'agit bien de Bash) :

#!/bin/bash

function testCaractere
{
UN_CARACTERE="$1"
echo -n "${UN_CARACTERE} est "
[[ "${UN_CARACTERE}" =~ [[:digit:]] ]] && echo "numérique" || echo "non numérique";
}

testCaractere "A"
testCaractere "5"

Dans tous les cas, on peut écrire une fonction de la sorte :

#!/bin/bash

function estNumerique
{
 [[ "$1" =~ [[:digit:]] ]]
 return $?
}

if estNumerique "A"; then echo "A est numerique"; else echo "A est non numérique"; fi
if estNumerique "5"; then echo "5 est numerique"; else echo "5 est non numérique"; fi

-- Lucid Lynx --

Hors ligne

#4 Le 27/02/2009, à 18:21

quimporte

Re : Bash : test d'un caractere

inutile de recourir à =~

function estNumerique
{
 [[ "$1" = [0-9] ]]
}
estNumerique "A" && echo "A est numerique" || echo "A est non numérique"
estNumerique "5" && echo "5 est numerique" || echo "5 est non numérique"

#5 Le 27/02/2009, à 21:07

Totor

Re : Bash : test d'un caractere

quimporte a écrit :

inutile de recourir à =~

function estNumerique
{
 [[ "$1" = [0-9] ]]
}
estNumerique "A" && echo "A est numerique" || echo "A est non numérique"
estNumerique "5" && echo "5 est numerique" || echo "5 est non numérique"

c'est vrai...
j'avais en tête l'ER [[:digit:]]\+ qui nécessitait le tild.


-- Lucid Lynx --

Hors ligne

#6 Le 03/03/2009, à 02:03

cristobal78

Re : Bash : test d'un caractere

pour alexduf

le 1er exemple sur Comment ca marche ... ne marche pas, même en supprimant les blancs entre les [ [ et les ] ]

D'ailleurs pourquoi les avoir mis ??? si c'est pour qu'on les enlève.

Qu'on mette 314 ou toto le résultat est le même.


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#7 Le 03/03/2009, à 15:26

flo45

Re : Bash : test d'un caractere

Re bonjour,

Merci pour vos réponses big_smile

Je suis confronté a un autre probleme :

Donc j'ai une variable X, qui contient le numéro d'une ligne de mon script (X=4 par exemple) et donc j'aimerais pouvoir extraire tout le contenu de ma ligne X (donc ligne 4), est ce possible ?

Merci encore pour votre aide smile

#8 Le 03/03/2009, à 16:18

alexduf

Re : Bash : test d'un caractere

cristobal78 a écrit :

pour alexduf

le 1er exemple sur Comment ca marche ... ne marche pas, même en supprimant les blancs entre les [ [ et les ] ]

ah! toutes mes excuses tongue

Hors ligne

#9 Le 03/03/2009, à 16:41

cristobal78

Re : Bash : test d'un caractere

pas grave alexduf

tu es tout excusé.;)

Mais si tu es fort en programmation pourrais tu nous expliquer en détail ce que fait (ou plutot ce que devrait faire le "grep" dans l'instruction fournie sur CCM (exemple 1) :

if [ "$(echo $var | grep "^[ [:digit:] ]*$")" ]

ce que je comprends :

Le résultat de echo $var est refilé à grep. Jusque là ça va.

[:digit:] je comprends, c'est dans le man mais avec des [ simples pas des [[ doubles.

^ et $ correspondent à des des chaines vides en début et fin de ligne. C'est quoi ce bazar ?

Par ailleurs je ne suis pas resté bras croisé sur ces 3 test de valeurs numériques. Même si je ne suis pas un cador ils ne me paraissent pas très au point. Il suffit de les tester avec une variable telle que
var=2 z
pour qu'ils plantent.

Finalement moi qui comme certains sur ce fil voudrait disposer d'un test efficace sur le type d'une variable je reste sur ma faim.:(

sos wink

a+


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#10 Le 03/03/2009, à 17:25

flo45

Re : Bash : test d'un caractere

un petit up, j'ai tester avec du grep pas moyen d'y arrivé .. peut etre avec un awk mais jvois pas trop là sad

#11 Le 03/03/2009, à 19:08

alexduf

Re : Bash : test d'un caractere

Ben la fonction de Totor fonctionne à merveille :

if [ estNumerique "$Mavar" ]; then
   # je fais un truc avec ma var
else
   # j'affiche un gros message d'erreur
fi

[edit] : woups, j'avais pas vu il y a une deuxième question. C'est pas une question pour un cours ou un TP des fois ? parce que sinon, je préfère te laisser chercher.
Bon un indice : tail et head [/edit]

Dernière modification par alexduf (Le 03/03/2009, à 19:10)

Hors ligne

#12 Le 03/03/2009, à 19:25

AnsuzPeorth

Re : Bash : test d'un caractere

J'apporte, avec mes peu de connaissances, ma pierre à l'édifice smile

cristobal78 a écrit :

if [ "$(echo $var | grep "^[ [:digit:] ]*$")" ]

^ → début de ligne
* → répétition du caractère précédent
$ → fin de ligne


cristobal78 a écrit :

Même si je ne suis pas un cador ils ne me paraissent pas très au point. Il suffit de les tester avec une variable telle que
var=2 z
pour qu'ils plantent.

vous avez eu la réponse par un des maitre en la matiere, donc, le problème vient d'ailleurs !

var=2 z
Une variable avec un espace sans protection...!
fais un echo $var, tu verras le résultat, c'est normal que le z ne soit pas pris en compte.

flo45 a écrit :

Donc j'ai une variable X, qui contient le numéro d'une ligne de mon script (X=4 par exemple) et donc j'aimerais pouvoir extraire tout le contenu de ma ligne X (donc ligne 4), est ce possible ?

man grep smile

EDIT:autant pour moi, je croyais qu'il y avait ce qu'il faut dans grep, mais pas moyen (pas reussi).... utilise sed, regarde dans ma signature.

EDIT2: c'est étonnant,avec [[:digit:]] sans le tild, une var de type "5z", le test fonctionne, avec le tild, il échoue !? Avec [0-9] pas de soucis

Dernière modification par AnsuzPeorth (Le 03/03/2009, à 19:51)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#13 Le 03/03/2009, à 21:27

Totor

Re : Bash : test d'un caractere

flo45 a écrit :

Donc j'ai une variable X, qui contient le numéro d'une ligne de mon script (X=4 par exemple) et donc j'aimerais pouvoir extraire tout le contenu de ma ligne X (donc ligne 4), est ce possible ?

il existe effectivement des solutions, tels que (liste non exhaustive) :
avec awk :

awk -v numligne=${X} 'NR==numligne' <fichier>

toujours avec awk :

export X
awk 'NR==ENVIRON["X"]' <fichier>

avec sed :

sed -n "${X}p" <fichier>

et si l'on veut faire dans le tordu :

grep -n ".*" <fichier>|grep "^${X}:"|sed "s/^${X}://"

ou

head -${X} <fichier>|tail -1

etc....


-- Lucid Lynx --

Hors ligne

#14 Le 03/03/2009, à 21:47

Totor

Re : Bash : test d'un caractere

alexduf a écrit :

Ben la fonction de Totor fonctionne à merveille :

if [ estNumerique "$Mavar" ]; then
   # je fais un truc avec ma var
else
   # j'affiche un gros message d'erreur
fi

ma fonction ne fonctionne que s'il n'y a qu'un seul caractère.
si il y en a plusieurs, il faut effectuer une légère modification (j'y fais d'ailleurs référence lors de ma réponse à quimporte)
:

function estNumerique
{
 [[ "$1" =~ ^[[:digit:]]+$ ]]
}

-- Lucid Lynx --

Hors ligne

#15 Le 03/03/2009, à 22:07

Totor

Re : Bash : test d'un caractere

AnsuzPeorth a écrit :

EDIT2: c'est étonnant,avec [[:digit:]] sans le tild, une var de type "5z", le test fonctionne, avec le tild, il échoue !? Avec [0-9] pas de soucis

Rien d'étonnant :
Avec le tild, la chaine se trouvant à droite du tild est considérée comme une expression régulière étendue. L'expression simple [[:digit:]] (ou [0-9]) indique "contient au moins 1 chiffre". Ce qui est le cas avec 5z.

Sans le tild, l'expression de droite doit vérifier les régles d'expansion de noms bash et doit être respectée en totalité lors de la comparaison. Or, en bash [0-9] signifie "juste un chiffre"

cristobal78 a écrit :

Par ailleurs je ne suis pas resté bras croisé sur ces 3 test de valeurs numériques. Même si je ne suis pas un cador ils ne me paraissent pas très au point. Il suffit de les tester avec une variable telle que
var=2 z
pour qu'ils plantent.

Finalement moi qui comme certains sur ce fil voudrait disposer d'un test efficace sur le type d'une variable je reste sur ma faim.sad

la demande portait sur un caractère (et non sur une chaine).
outre le fait de ne pas être un "cador", prends le temps de lire et de comprendre une ligne ne semble pas non plus être ton fort !


-- Lucid Lynx --

Hors ligne

#16 Le 04/03/2009, à 01:22

cristobal78

Re : Bash : test d'un caractere

Il est pas sympa avec moi monsieur totor.;)

Moi ça fait une semaine que je commence à lire et à essayer de comprendre la ligne de commande. Avant je n'avais jamais vu ça.
J'ai assez vite compris qu'il serait intéressant de savoir dire si une variable est numérique ou non et c'est comme ça (via google) que je suis arrivé dans cette discussion initiée par flo45.

En lisant ce fil où des gens manifestement BEAUCOUP plus forts que moi semblent avoir du mal à se mettre d'accord (il y a pas loin de 15 post), force est de reconnaitre qu'il n'est pas si simple que ça de savoir si une variable est numérique ou non. C'est peut être simple pour certains mais pas pour tous.

Pour le débutant il faut avouer que :
if [ "$(echo $var | grep "^[ [:digit:] ]*$")" ]
n'est pas facile à comprendre.

Merci à AnsuzPeorth pour l'info.:)
J'ai bien lu dans le man que
^ → début de ligne
* → répétition du caractère précédent
$ → fin de ligne

mais je ne comprends pas bien l'utilisation qui en est faite dans la condition if ci-dessus.
Cela veut-il dire "qui commence par un chiffre, qui est suivi de chiffres et qui finit par un chiffre ? C'est ça ?

Enfin pour reprendre la dernière ligne de totor, il est vrai que flo45 a posé une question relative à un caractère mais le lien donné ici par alexduf envoyant sur CCM proposait une méthode portant sur une chaine de caractère, d'où ma tentative malheureuse avec var=2 z

a+


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#17 Le 04/03/2009, à 10:14

alexduf

Re : Bash : test d'un caractere

cristobal78 a écrit :

mais je ne comprends pas bien l'utilisation qui en est faite dans la condition if ci-dessus.
Cela veut-il dire "qui commence par un chiffre, qui est suivi de chiffres et qui finit par un chiffre ? C'est ça ?

oui c'est l'idée.

sans le "^" ni le "$", ça aurais voulu dire "qui contient un ou plusieurs chiffres", mais avec pourquoi pas autre chose avant et après.

comme a15b ou a15 ou 15b ou 15

après pour découper un fichier et n'en garder qu'une ligne je trouve le head | tail très pratique., mais, ça c'est les goûts et les couleurs.

cristobal78 a écrit :

En lisant ce fil où des gens manifestement BEAUCOUP plus forts que moi semblent avoir du mal à se mettre d'accord (il y a pas loin de 15 post), force est de reconnaitre qu'il n'est pas si simple que ça de savoir si une variable est numérique ou non. C'est peut être simple pour certains mais pas pour tous.

En fait il existe à peu près autant de manières de faire quelque chose en bash, qu'il existe de programmeurs en bash. D'où les 15 réponses à chaque question, et les désaccords entre les différents membres.

Hors ligne

#18 Le 04/03/2009, à 10:30

cristobal78

Re : Bash : test d'un caractere

merci alexduf

je vais re-essayer et re-tester cette instruction !

a+


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#19 Le 04/03/2009, à 12:54

cristobal78

Re : Bash : test d'un caractere

après plusieurs essais de
echo $var | grep "^[[:digit:]]*$"
j'ai constaté des choses curieuses :

cas            var                           renvoie
-------       -------------             ---------------------------------------
1               222                          numérique                     
2               zzzz                         pas numérique
3               222zzz                      pas numérique
4               222 zzz                     222 donc numérique, qu'est devenu le zzz ?
5               zzz 222                     pas numérique

6               222,75                      pas numérique
7               222.75                      pas numérique
8               222 75                      222 donc numérique, le 75 passe à la trappe

Les réponses sont conformes évidement à ce que la commande est censée faire mais cette commande n'est pas totalement "rigoureuse" car elle ne réagit bien que sur les cas 1, 2, 3 et 5.
Sinon :
- le cas 4 n'est clairement pas un nombre !
- au moins l'un des des cas 6 ou 7 devrait exprimer un nombre (selon que le séparateur décimal est un point ou une virgule),
- le cas 8 provoque le même résulta que le cas 4 qui n'a pourtant rien à voir.

Donc dans un script si l'on veut vraiment et sans coup férir s'assurer qu'un chaine est numérique cette commande me parait insuffisante. Qu'en pensent les "bons scripteurs" ?

a+

Dernière modification par cristobal78 (Le 04/03/2009, à 12:55)


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#20 Le 04/03/2009, à 13:12

alexduf

Re : Bash : test d'un caractere

cristobal78 a écrit :

4               222 zzz                     222 donc numérique, qu'est devenu le zzz ?
8               222 75                      222 donc numérique, le 75 passe à la trappe

essaye d'entourer ta variable par des guillemets :

echo "$var" | grep "^[[:digit:]]*$"
cristobal78 a écrit :

6               222,75                      pas numérique
7               222.75                      pas numérique

echo "$var" | grep "^[[:digit:]]+[,.]?[[:digit:]]*$"

j'ai pas testé mais ça devrais faire l'affaire

Dernière modification par alexduf (Le 04/03/2009, à 13:13)

Hors ligne

#21 Le 04/03/2009, à 13:47

cristobal78

Re : Bash : test d'un caractere

ça n'a pas l'air de marcher.
J'ai mis les 2 options dans un script nommé testnum2 pour tester plus vite :

#!/bin/sh
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# nom du script = testnum2
# Fonction du script = teste si parametre est numérique ou non
# Syntaxe = ./testnum2 parametre
# Note = 
# jcc/04.03.2009
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
var=$1
echo "commande 1"
echo "$var"|grep "^[[:digit:]]*$"
echo "var=$var et \$?=$?"

echo "commande 2"
echo "$var" | grep "^[[:digit:]]+[,.]?[[:digit:]]*$"
echo "var=$var et \$?=$?"

testnum2 123 donne :

testnum2 123
commande 1
123
var=123 et $?=0
commande 2
var=123 et $?=1

donc dans le 1er cas 123 est numérique et pas dans le 2-ème.

C'est pas de la tarte.

a+


Laptop Lenovo Ubuntu 20.04 LTS / DELL Mint 20.2 - XFCE / Laptop HP Mint 20.2 - XFCE

Hors ligne

#22 Le 04/03/2009, à 14:40

Totor

Re : Bash : test d'un caractere

Si ça peut vous aider ...

function estNumerique { [[ "$1" =~ "^[+-]{0,1}([[:digit:]]+[,.]){0,1}[[:digit:]]+$" ]]; }

$ estNumerique "222 zzz" && echo numerique || echo non numerique
non numerique
$ estNumerique "22,75" && echo numerique || echo non numerique
numerique
$ estNumerique "22 75" && echo numerique || echo non numerique
non numerique
$ estNumerique "+22 75" && echo numerique || echo non numerique
non numerique
$ estNumerique "+22,75" && echo numerique || echo non numerique
numerique


-- Lucid Lynx --

Hors ligne

#23 Le 04/03/2009, à 14:41

AnsuzPeorth

Re : Bash : test d'un caractere

Vous etes encore à vous battre avec ça ???


var="123 zzz"
echo "$var"|grep "^[[:digit:]]*$" 
#n'est pas numérique, donc pas de sortie (ca fonctionne correctement)

maintenant pour tester un nombre a virgule; utilise la comparaison inverse, test si lettre:

[^[:digit:]]
#ou
[[:alpha:]]

var="r12"
echo "$var"| grep "[^[:digit:]]"
#contient au moins un caractère non numérique
r12

Dernière modification par AnsuzPeorth (Le 04/03/2009, à 15:09)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#24 Le 04/03/2009, à 14:51

AnsuzPeorth

Re : Bash : test d'un caractere

Juste un petit mot en passant:

A CAUSE de Totor,
Voilà mon évolution:

echo $var | grep truc #2 commandes un pipe
grep truc <<< $var   #1 commande et une redirection
# et maintenant, le ponpon
$var =~ truc              #une comparaison
#on peut faire encore plus court ?

J'en apprends des choses ici smile

EDIT:une petite question qd meme smile
Pourquoi les " sont necessaire avec l'utilisation d'une ER avec grep pour que ca fonctionne
et inversement avec =~ (si ", marche po ???)

Dernière modification par AnsuzPeorth (Le 04/03/2009, à 15:00)


Interface graphique pour bash, python ou autre: glade2script
Support Tchat: http://chat.jabberfr.org/muckl_int/inde … ade2script  (Hors ligne)

Hors ligne

#25 Le 05/03/2009, à 11:21

Totor

Re : Bash : test d'un caractere

AnsuzPeorth a écrit :
var="123 zzz"
echo "$var"|grep "^[[:digit:]]*$" 
#n'est pas numérique, donc pas de sortie (ca fonctionne correctement)

maintenant pour tester un nombre a virgule; utilise la comparaison inverse, test si lettre:

[^[:digit:]]
#ou
[[:alpha:]]

var="r12"
echo "$var"| grep "[^[:digit:]]"
#contient au moins un caractère non numérique
r12

Ce n'est pas suffisant... que fais-tu des signes + et -, de la virgule, quantité et position ?
C'est pourquoi j'ai fourni une ER complète.


-- Lucid Lynx --

Hors ligne