#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
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 : Giroll – Services libres : TdCT.org
Hide in your shell, scripts & astuces : applications dans un tunnel – smart wget – trouver des pdf – install. auto de paquets – sauvegarde 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
o/ pingouinux & Postmortem
edit : rien
Dernière modification par nesthib (Le 23/01/2014, à 06:12)
GUL Bordeaux : Giroll – Services libres : TdCT.org
Hide in your shell, scripts & astuces : applications dans un tunnel – smart wget – trouver des pdf – install. auto de paquets – sauvegarde 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
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
Merci encore
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
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
@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
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
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 : Giroll – Services libres : TdCT.org
Hide in your shell, scripts & astuces : applications dans un tunnel – smart wget – trouver des pdf – install. auto de paquets – sauvegarde 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 !!!
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
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
- 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
Encore merci à tous
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 : Giroll – Services libres : TdCT.org
Hide in your shell, scripts & astuces : applications dans un tunnel – smart wget – trouver des pdf – install. auto de paquets – sauvegarde 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