Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Manipulation de cha̓®ne

3 réponses
Avatar
Olivier Miakinen
[diapublication, suivi modifiable si nécessaire]

Bonjour,

Préambule :
Ma question porte sur le kornshell (ksh) sur une machine GNU/Linux,
mais selon que la réponse utilise une builtin du shell ou une commande
externe, elle sera peut-être plus en charte sur fclr, voire un autre
groupe, plutÍ´t que sur fcolc o͹ j'ai placé le suivi. Répondez lÍ  o͹
ça vous semble le mieux ! (Merci.)

Dans un ksh j'ai une variable qui contient quatre chiffres ou plus, par
exemple "314159". Je voudrais obtenir une autre variable dans laquelle
les trois premiers chiffres sont suivis chacun de la séquence "\.".

"314159" -> "3\.1\.4\.159"
"1234" -> "1\.2\.3\.4"
"123456789" -> "1\.2\.3\.456789"

Bien sÍ»r je pourrais écrire "${v:0:1}\.${v:1:1}\.${v:2:1}\.${v:3}", mais
y a-t-il plus simple ?


P.-S. : J'ai la même question, mais pour le cas o͹ chaque chiffre (sauf
éventuellement le dernier) doit être suivi de la séquence.

"314159" -> "3\.1\.4\.1\.5\.9"
"1234" -> "1\.2\.3\.4"
"123456789" -> "1\.2\.3\.4\.5\.6\.7\.8\.9"

Cordialement,
--
Olivier Miakinen

3 réponses

Avatar
Jacques L'helgoualc'h
Le 21-05-2022, Olivier Miakinen a écrit :
[diapublication, suivi modifiable si nécessaire]
Bonjour,

Bonsoir,
Préambule :
Ma question porte sur le kornshell (ksh) sur une machine GNU/Linux,
mais selon que la réponse utilise une builtin du shell ou une commande
externe, elle sera peut-être plus en charte sur fclr, voire un autre
groupe, plutÍ´t que sur fcolc o͹ j'ai placé le suivi. Répondez lÍ  o͹
ça vous semble le mieux ! (Merci.)
Dans un ksh j'ai une variable qui contient quatre chiffres ou plus, par
exemple "314159". Je voudrais obtenir une autre variable dans laquelle
les trois premiers chiffres sont suivis chacun de la séquence ".".
"314159" -> "3.1.4.159"
"1234" -> "1.2.3.4"
"123456789" -> "1.2.3.456789"
Bien sÍ»r je pourrais écrire "${v:0:1}.${v:1:1}.${v:2:1}.${v:3}", mais
y a-t-il plus simple ?

$ echo 2718281828459045 |
sed -nre '/^[0-9]+$/!{s/^/Fuck /p;q};:x;s/([0-9])([0-9])/1.2/;/(.[0-9]){3}/{p;q};bx'
2.7.1.8281828459045
Sans le contrÍ´le initial, plus simple :
sed -nre ':x;s/([0-9])([0-9])/1.2/;/...../{p;q};bx'
Il faudrait insérer un « /[0-9][0-9]/!{p;Q} », ou modifier le test initial,
si tu es assez pervers pour essayer un nombre de moins de 4 chiffres :)
P.-S. : J'ai la même question, mais pour le cas o͹ chaque chiffre (sauf
éventuellement le dernier) doit être suivi de la séquence.

$ echo 2718281828459045 |
sed -nre ':x;s/([0-9])([0-9])/1.2/g;tx;p;q'
2.7.1.8.2.8.1.8.2.8.4.5.9.0.4.5
Il faut deux passes du s///g d'insertion (ou accepter/supprimer un point final) :
$ echo 2718281828459045 |
sed -nre ':x;s/([0-9])([0-9])/1.2/gp;tx;q'
2.71.82.81.82.84.59.04.5
2.7.1.8.2.8.1.8.2.8.4.5.9.0.4.5
Le plus simple :
echo 2718281828459045 |sed -e 's/[0-9]/&./g;s/.$//'
2.7.1.8.2.8.1.8.2.8.4.5.9.0.4.5
Avatar
Olivier Miakinen
Bonjour Jacques,
Le 22/05/2022 00:12, Jacques L'helgoualc'h a écrit :
Bien sÍ»r je pourrais écrire "${v:0:1}.${v:1:1}.${v:2:1}.${v:3}", mais
y a-t-il plus simple ?

$ echo 2718281828459045 |
sed -nre '/^[0-9]+$/!{s/^/Fuck /p;q};:x;s/([0-9])([0-9])/1.2/;/(.[0-9]){3}/{p;q};bx'
2.7.1.8281828459045

Ouah ! Je n'appellerais pas ça « plus simple », mais avec l'aide de
« man sed » tu viens de me faire découvrir la puissance de cette
commande que j'étais loin de soupçonner !
Je viens d'apprendre :
- le « ! » pour ne pas exécuter une commande si l'adresse ne matche pas ;
- les blocs de commandes avec « { » et « } » ;
- l'option -n pour supprimer l'auto-print ;
- le « p;q » pour afficher le résultat puis quitter ;
- les boucles, avec un label (:x) et un branchement (bx).
Je connaissais le reste, mais c'était un usage tellement limité !
Sans le contrÍ´le initial, plus simple :
sed -nre ':x;s/([0-9])([0-9])/1.2/;/...../{p;q};bx'
Il faudrait insérer un « /[0-9][0-9]/!{p;Q} », ou modifier le test initial,
si tu es assez pervers pour essayer un nombre de moins de 4 chiffres :)

Oui et oui (et non, je ne suis pas assez pervers pour ça, des tests
préliminaires évitent d'avoir des nombres plus petits).
P.-S. : J'ai la même question, mais pour le cas o͹ chaque chiffre (sauf
éventuellement le dernier) doit être suivi de la séquence.

$ echo 2718281828459045 |
sed -nre ':x;s/([0-9])([0-9])/1.2/g;tx;p;q'
2.7.1.8.2.8.1.8.2.8.4.5.9.0.4.5

Ok, du coup j'ai appris aussi les branchements conditionnels avec t ou T.
Il faut deux passes du s///g d'insertion (ou accepter/supprimer un point final) :
$ echo 2718281828459045 |
sed -nre ':x;s/([0-9])([0-9])/1.2/gp;tx;q'
2.71.82.81.82.84.59.04.5
2.7.1.8.2.8.1.8.2.8.4.5.9.0.4.5

Ok.
Le plus simple :
echo 2718281828459045 |sed -e 's/[0-9]/&./g;s/.$//'
2.7.1.8.2.8.1.8.2.8.4.5.9.0.4.5

Bon sang mais c'est bien sÍ»r ! Je m'en veux de ne pas y avoir pensé
moi-même, parce que je connaissais tout ce qu'il fallait pour arriver
Í  cette solution.
Un grand merci Í  toi, c'est vraiment génial cette commande.
--
Olivier Miakinen
Avatar
Jacques L'helgoualc'h
Le 21-05-2022, Olivier Miakinen a écrit :
Bonjour Jacques,
Le 22/05/2022 00:12, Jacques L'helgoualc'h a écrit :
Bien sÍ»r je pourrais écrire "${v:0:1}.${v:1:1}.${v:2:1}.${v:3}", mais
y a-t-il plus simple ?

$ echo 2718281828459045 |
sed -nre '/^[0-9]+$/!{s/^/Fuck /p;q};:x;s/([0-9])([0-9])/1.2/;/(.[0-9]){3}/{p;q};bx'
2.7.1.8281828459045

Ouah ! Je n'appellerais pas ça « plus simple », mais avec l'aide de
« man sed » tu viens de me faire découvrir la puissance de cette
commande que j'étais loin de soupçonner !

Sed est Turing-complet :)
Je viens d'apprendre :
- le « ! » pour ne pas exécuter une commande si l'adresse ne matche pas ;
- les blocs de commandes avec « { » et « } » ;
- l'option -n pour supprimer l'auto-print ;
- le « p;q » pour afficher le résultat puis quitter ;
- les boucles, avec un label (:x) et un branchement (bx).
Je connaissais le reste, mais c'était un usage tellement limité !

J'avais envisagé d'utiliser le « hold-space » pour limiter un s///g :)
[...]
Le plus simple :
echo 2718281828459045 |sed -e 's/[0-9]/&./g;s/.$//'
2.7.1.8.2.8.1.8.2.8.4.5.9.0.4.5

Bon sang mais c'est bien sÍ»r ! Je m'en veux de ne pas y avoir pensé
moi-même, parce que je connaissais tout ce qu'il fallait pour arriver
Í  cette solution.
Un grand merci Í  toi, c'est vraiment génial cette commande.

de rien !