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 22/01/2014, à 07:38

Link_Octree

[Question] Détecter la nature et longueur d'une chaine de caractères

Hello,

J'ai un fichier .txt contenant plusieurs valeurs sur la même ligne style:
NOM PRENOM NUM_CLIENT NUM_TEL

J'aimerais pouvoir isoler le contenu de NUM_CLIENT et NUM_TEL au sein de deux variables distinctes.
J'avais pensé à faire celà avec des cut en me basant sur les espaces, mais en cas de nom composé orthographié avec un espace celà pose problème si jamais nom et num_client sont séparés non pas par un espace mais par un tiret celà ne marche plus non plus...

Est-il possible de faire celà en se basant sur la nature et la longueur de la chaine de caractère du genre:
La chaine de caractère qui contient 5 chiffres sera le numéro de client, la chaine qui contient 10 chiffres sera le numéro de téléphone ?

Sauriez-vous comment faire celà svp ?

Merci d'avance smile

Dernière modification par Link_Octree (Le 22/01/2014, à 07:39)

Hors ligne

#2 Le 22/01/2014, à 08:11

nesthib

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

Avec sed, tu peux définir une expression rationnelle qui correspond à ta chaîne de caractères. Ici je définis la chaîne comme un ensemble non nul de caractères n'étant pas des chiffres, suivi d'une suite de cinq chiffres, d'un espaces et d'une suite de dix chiffres. Les suites de chiffres sont enregistrée dans les variables \1 et \2, ce qui permet de les afficher par la suite.

sed 's/[^0-9]\+\([0-9]\{5\}\) \([0-9]\{10\}\)/numéro client : \1\ntéléphone : \2/' <<<"NOM PRENOM blabla 01234 0123456789"

Bien entendu il ne s'agit que d'un exemple et il te faudra l'adapter à ce que tu veux faire.


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#3 Le 22/01/2014, à 08:23

pingouinux

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

Bonjour,
Si tu veux juste récupérer les deux derniers champs, tu peux essayer ceci :

while read num_client num_tel
do
   echo num_client="$num_client" num_tel="$num_tel"
done < <(awk -F"[- ]+" '{print $(NF-1)" "$NF}' fic.txt)

Si ça ne convient pas, peux-tu montrer quelques lignes du fichier .txt, et préciser ta demande ?

Hors ligne

#4 Le 22/01/2014, à 12:30

Postmortem

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

Salut,

$ cat test.txt
De La Motte Jean-Jacques 45624 0156843465
Durant Robert-56318 0265656565
Dupont-Marie-12345-0102030405
Hollande-François 98765-0109080706

$ while IFS=' -' read -a infos; do echo "Numéro client : ${infos[@]: -2:1}"; echo "Téléphone : ${infos[@]: -1}"; done < test.txt
Numéro client : 45624
Téléphone : 0156843465
Numéro client : 56318
Téléphone : 0265656565
Numéro client : 12345
Téléphone : 0102030405
Numéro client : 98765
Téléphone : 0109080706

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

Hors ligne

#5 Le 23/01/2014, à 06:11

nesthib

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

\o/ un concours de variantes, ça faisait longtemps smile
o/ pingouinux & Postmortem

edit : rien tongue

Dernière modification par nesthib (Le 23/01/2014, à 06:12)


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#6 Le 23/01/2014, à 20:18

Link_Octree

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

Re, et un sincère merci à vous trois pour votre précieuse aide smile

Je suis plutôt parti sur le code de Postmortem car c'est celui qui me semblait le plus lisible, et que je pensais donc le plus facile à modifier.

J'ai repensé un peu mes besoins, et il semblerait préférable, dans mon cas précis d'extraire finalement les données voulues non plus d'un .txt mais d'une variable déclaré plus tôt dans le script.
J'ai donc voulu modifier le code en fonction, sans trop de succés jusqu'à présent je dois dire:

#!/bin/bash

variable='PELTIER ALEXANDRE 40000121314 15634'

while IFS=' -' read -a extracteur; do
        let "num_client = ${extracteur[@]: -2:1}";
        let "num_tel = ${extracteur[@]: -1}";
done < $variable

Pour être sincère je ne comprends pas du tout l'utilité de la dernière ligne, j'ai déja utilisé les redirection ">" mais là çà semble être une sorte de redirection inversée, çà m'intrigue tongue

Merci encore smile

Hors ligne

#7 Le 23/01/2014, à 20:26

pingouinux

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

En adaptant ce que tu as fait :

variable='PELTIER ALEXANDRE 40000121314 15634'

while IFS=' -' read -a extracteur; do
        num_client="${extracteur[@]: -2:1}";
        num_tel="${extracteur[@]: -1}";
done <<<"$variable"

echo num_client="$num_client" num_tel="$num_tel"

Ce qui donne :

num_client=40000121314 num_tel=15634

Ajouté :
Pour répondre à la question sur les redirections :

commande <entrée_standard >sortie_standard

Dernière modification par pingouinux (Le 23/01/2014, à 20:38)

Hors ligne

#8 Le 23/01/2014, à 20:52

Postmortem

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

Salut,
Plein de commandes se servent de l'entrée standard ; par exemple, si tu passes la commande suivante :

read toto

Tu pourras ensuite taper du texte, et une fois que tu auras appuyer sur Entrée, ce texte ira dans la variable toto.
Si tu fais :

read toto < fichier

Plutôt que de te rendre la main pour que tu rentres du texte, la variable toto sera alimentée avec la première ligne du fichier ; l'entrée standard classique (le clavier) est remplacée par le fichier.
Donc en faisant :

while read toto
do
   Commandes utilisant la variable toto
done < fichier

Pour chaque ligne du fichier, on affecte la ligne à la variable toto, puis on exécute les commandes.

Pour ton cas, plutôt que d'utiliser une variable, tu pourrais directement utiliser un tableau, on s'affranchit ainsi des séparateurs embêtants en mettant chaque élément entre guillemets :

infos=("PELTIER" "ALEXANDRE" "40000121314" "15634")
echo "Num client : ${infos[2]}"
echo "Téléphone : ${infos[3]}"

Édit : trop lent à rédiger le message sur mon tel, pingouinux était à l'affût ! ;-)

Dernière modification par Postmortem (Le 23/01/2014, à 20:59)


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

Hors ligne

#9 Le 23/01/2014, à 21:26

pingouinux

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

@Postmortem : il est vrai que nous nous intéressons souvent au même genre de dicussions smile

Hors ligne

#10 Le 28/01/2014, à 00:09

Link_Octree

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

@pingouinux: Merci pour ta variante adaptée à mon script, j'ai testé et çà fonctionne parfaitement big_smile

@Postmortem: Peut-être que les séparateurs dont tu parles pourraient me servir pour une autre fonction:

J'ai en entrée une chaine de caractère de ce style (je ne peux pas influer sur la syntaxe de celle-ci):

7774445	27/01/14 21:35:14	70326	247525990412

Là encore je voudrais isoler ces champs dans des variables distinctes, le problème c'est que certaines données ont l'air séparés les unes des autres par des espaces, d'autres par des tabulations...

Ca fait une heure que j'essaie beaucoup de chose en combinant tr & cut pour supprimer les espaces multiples, en essayant une multitudes de commande sed dont la signification réelle m'échappe, sans succés hmm

Est-il possible de remplacer les tabs par des espaces uniques par exemple pour faire le reste avec cut ?
Sinon par curiosité, est-il possible d'isoler ces données dans des variables distinctes en fonction de leur format (style la chaine de 12 caractères sera affectée à la $variable_1, celle de 5 caractères à la $variable_2, etc ?

Merci encore pour votre aide, c'est très intéressant d'en apprendre un peu plus sur le shell smile

Hors ligne

#11 Le 28/01/2014, à 02:18

Postmortem

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

Salut,

ma_chaine="7774445	27/01/14 21:35:14	70326	247525990412"
tableau=( $ma_chaine )

Tu pourras ainsi appeler chaque élément séparément : ${tableau[0]}, ${tableau[1]}, ${tableau[2]} etc...
Ça fonctionne qu'il y ait des espaces ou des tabulations (chaque suite d'espaces/tabulations est vue comme un séparateur unique)


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

Hors ligne

#12 Le 28/01/2014, à 02:39

nesthib

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

Tu peux facilement ajouter la prise en charge d'un séparateur alternatif à ma commande ou à celle de pingouinux.
pour la mienne :

sed 's/[^0-9]\+\([0-9]\{5\}\)[ \t]\([0-9]\{10\}\)/numéro client : \1\ntéléphone : \2/' <<<"NOM PRENOM blabla 01234 0123456789"

(grâce au [ \t] qui équivaut à espace ou tabulation)
pour celle de pingouinux :

while read num_client num_tel
do
   echo num_client="$num_client" num_tel="$num_tel"
done < <(awk -F"[- \t]+" '{print $(NF-1)" "$NF}' fic.txt)

GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#13 Le 28/01/2014, à 11:26

Postmortem

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

Salut,
Concours de variantes !!! tongue

while IFS="$IFS-" read -a infos
do
   echo "${infos[0]}"
   echo "${infos[1]}"
   # ...
done < test.txt

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

Hors ligne

#14 Le 30/01/2014, à 21:00

Link_Octree

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

Merci encore pour toutes ces solutions proposées, vraiment sympa smile

Je suis pas loin d'être arrivé à ce que je veux, il me reste deux petits trucs que je sais pas faire, et j'arrive pas à trouver les bons termes à googler:

- En admettant que ma variable num_tel="0506070809", je voudrais masquer partiellement le numéro dans une variable style num_tel_partiel="05XXXX0809".
La piste que je privilégie est de remplacer les charactères 3 à 6 de ma variable par des X (celà pourrait me servir à d'autre choses également). Si possible sans sed, je doute pas de la puissance du truc mais j'ai du mal avec la syntaxe hmm

- Je voudrais à présent intégrer les valeurs de certaines variables dans un genre de squelette html.
Là aussi j'ai un début d'idée, utiliser les balises html disposant d'un id unique pour me repérer dans la page:
Repérer la bonne ligne en utilisant grep, puis insérer la valeur de ma variable avec echo. Le soucis c'est que je ne sais pas comment placer le "curseur" au bon endroit dans la ligne (<div id="num_tel">ici</div>). Même chose, variante sans sed privilégiée tongue

Encore merci à tous big_smile

Hors ligne

#15 Le 30/01/2014, à 21:10

nesthib

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

un exemple :

sed 's/[^0-9]\+\([0-9]\{5\}\)[ \t]\([0-9]\{2\}\)\([0-9]\{6\}\)\([0-9]\{2\}\)/numéro client : \1\ntéléphone : \2xxxx\3/' <<<"NOM PRENOM blabla 01234 0123456789"

GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#16 Le 30/01/2014, à 21:14

pingouinux

Re : [Question] Détecter la nature et longueur d'une chaine de caractères

sed est pourtant très adapté à la première demande :

$ num_tel="0506070809"
$ num_tel_partiel=$(sed -r 's/(..)....(....)/\1XXXX\2/' <<<"$num_tel")
$ echo "$num_tel_partiel"
05XXXX0809

Ajouté :
Ou bien

$ num_tel_partiel=$(awk '{print substr($0,1,2)"XXXX"substr($0,7)}' <<<"$num_tel")

Dernière modification par pingouinux (Le 30/01/2014, à 21:21)

Hors ligne