Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > fr.comp.os.unix > #8132 > unrolled thread

Shell : extraire d'une chaine plusieurs sous-chaines

Started byOlivier Miakinen <om+news@miakinen.net>
First post2025-11-25 19:08 +0100
Last post2025-12-21 21:19 +0100
Articles 20 on this page of 22 — 5 participants

Back to article view | Back to fr.comp.os.unix


Contents

  Shell : extraire d'une chaine plusieurs sous-chaines Olivier Miakinen <om+news@miakinen.net> - 2025-11-25 19:08 +0100
    Re: Shell : extraire d'une chaine plusieurs sous-chaines Christian Weisgerber <naddy@mips.inka.de> - 2025-11-25 19:45 +0000
      Re: Shell : extraire d'une chaine plusieurs sous-chaines Olivier Miakinen <om+news@miakinen.net> - 2025-11-25 22:36 +0100
        Re: Shell : extraire d'une chaine plusieurs sous-chaines Christian Weisgerber <naddy@mips.inka.de> - 2025-11-25 23:48 +0000
          Re: Shell : extraire d'une chaine plusieurs sous-chaines Olivier Miakinen <om+news@miakinen.net> - 2025-11-26 11:55 +0100
            Re: Shell : extraire d'une chaine plusieurs sous-chaines Olivier Miakinen <om+news@miakinen.net> - 2025-11-26 12:37 +0100
              Re: Shell : extraire d'une chaine plusieurs sous-chaines Olivier Miakinen <om+news@miakinen.net> - 2025-11-26 13:50 +0100
                Re: Shell : extraire d'une chaine plusieurs sous-chaines Christian Weisgerber <naddy@mips.inka.de> - 2025-11-26 21:58 +0000
                  Re: Shell : extraire d'une chaine plusieurs sous-chaines Olivier Miakinen <om+news@miakinen.net> - 2025-11-27 01:09 +0100
                    Re: Shell : extraire d'une chaine plusieurs sous-chaines Christian Weisgerber <naddy@mips.inka.de> - 2025-11-28 15:45 +0000
                      Re: Shell : extraire d'une chaine plusieurs sous-chaines Olivier Miakinen <om+news@miakinen.net> - 2025-12-08 14:27 +0100
              Re: Shell : extraire d'une chaine plusieurs sous-chaines Christian Weisgerber <naddy@mips.inka.de> - 2025-11-26 21:29 +0000
            Re: Shell : extraire d'une chaine plusieurs sous-chaines Christian Weisgerber <naddy@mips.inka.de> - 2025-11-26 21:16 +0000
              Re: Shell : extraire d'une chaine plusieurs sous-chaines Olivier Miakinen <om+news@miakinen.net> - 2025-11-27 00:52 +0100
    Re: Shell : extraire d'une chaine plusieurs sous-chaines Nicolas George <nicolas$george@salle-s.org> - 2025-11-25 20:32 +0000
      Re: Shell : extraire d'une chaine plusieurs sous-chaines Olivier Miakinen <om+news@miakinen.net> - 2025-11-25 22:42 +0100
      Re: Shell : extraire d'une chaine plusieurs sous-chaines Christian Weisgerber <naddy@mips.inka.de> - 2025-11-28 15:58 +0000
    Re: Shell : extraire d'une chaine plusieurs sous-chaines kurtz le pirate <kurtzlepirate@free.fr> - 2025-11-27 10:59 +0100
    Re: Shell : extraire d'une chaine plusieurs sous-chaines kurtz le pirate <kurtzlepirate@free.fr> - 2025-11-27 11:07 +0100
    Re: Shell : extraire d'une chaine plusieurs sous-chaines Doug713705 <doug.letough@free.fr> - 2025-12-20 12:30 +0000
      Re: Shell : extraire d'une chaine plusieurs sous-chaines Nicolas George <nicolas$george@salle-s.org> - 2025-12-20 13:44 +0000
      Re: Shell : extraire d'une chaine plusieurs sous-chaines Olivier Miakinen <om+news@miakinen.net> - 2025-12-21 21:19 +0100

Page 1 of 2  [1] 2  Next page →


#8132 — Shell : extraire d'une chaine plusieurs sous-chaines

FromOlivier Miakinen <om+news@miakinen.net>
Date2025-11-25 19:08 +0100
SubjectShell : extraire d'une chaine plusieurs sous-chaines
Message-ID<10g4rbq$2i1$1@cabale.usenet-fr.net>
[diapublication, suivi vers fr.comp.os.unix seul]

Bonjour,

Dans un script ksh, je cherche la façon la plus élégante d'extraire
d'une chaine plusieurs sous-chaines. Le cas réel est plus complexe
que celui que je vais exposer, mais je saurai extrapoler ensuite.


Supposons que j'ai une chaine constituée d'1 ou plusieurs lettres,
puis 1 chiffre, puis optionnellement d'autres lettres, puis encore
1 ou plusieurs chiffres. Pour fixer les idées, disons que la chaine
répondrait à la regex suivante :
   /[a-z]+[0-9][a-z]*[0-9]+/

Je voudrais extraire chaque partie dans une variable différente.
Quelques exemples :
 s="test1xyz27"  ->  v1="test" v2="1"  v3="xyz"  v4="27"
 s="aa9toto000"  ->  v1="aa"   v2="9"  v3="toto" v4="000"
 s="x012"        ->  v1="x"    v2="0"  v3=""     v4="12"

Bien sûr je sais le faire en autant d'étapes qu'il y a de parties
à récupérer, en obtenant les variables l'une après l'autre. Mais
existe-t-il un moyen plus direct ?


Quelques précisions :
- le ksh sur cette machine ne connait pas la syntaxe [[ ... =~ ... ]]
- mais j'ai accès à perl 5, sed, awk, et probablement d'autres outils
  unix standards.


[suivi par défaut vers fcou mais vous pouvez faire suivre ailleurs si
cela vous semble plus approprié]

Cordialement,
-- 
Olivier Miakinen

[toc] | [next] | [standalone]


#8133

FromChristian Weisgerber <naddy@mips.inka.de>
Date2025-11-25 19:45 +0000
Message-ID<slrn10ic1q0.25b8.naddy@lorvorc.mips.inka.de>
In reply to#8132
On 2025-11-25, Olivier Miakinen <om+news@miakinen.net> wrote:

> Supposons que j'ai une chaine constituée d'1 ou plusieurs lettres,
> puis 1 chiffre, puis optionnellement d'autres lettres, puis encore
> 1 ou plusieurs chiffres. Pour fixer les idées, disons que la chaine
> répondrait à la regex suivante :
>    /[a-z]+[0-9][a-z]*[0-9]+/

En regex basique, c'est
     /[a-z][a-z]*[0-9][a-z]*[0-9][0-9]*/

> Bien sûr je sais le faire en autant d'étapes qu'il y a de parties
> à récupérer, en obtenant les variables l'une après l'autre. Mais
> existe-t-il un moyen plus direct ?

S'il y a un caractère qui n'apparait pas dans la chaine, on peut
utiliser un outil externe pour couper la chaine en morceaux, séparer
les morceaux par ce caractère, et ...

while IFS='!' read v1 v2 v3 v4; do
	...
done <<EOF
$(sed 's/\([a-z][a-z]*\)\([0-9]\)\([a-z]*\)\([0-9][0-9]*\)/\1!\2!\3!\4/')
EOF

Attention ! Si on utilise éspace ou tab comme caractère de séparation,
le shell traite plusieurs éspaces/tabs comme un seul séparateur, donc
ça ne marche pas si un morceau est vide.

-- 
Christian "naddy" Weisgerber                          naddy@mips.inka.de

[toc] | [prev] | [next] | [standalone]


#8135

FromOlivier Miakinen <om+news@miakinen.net>
Date2025-11-25 22:36 +0100
Message-ID<10g57g3$20kd$1@cabale.usenet-fr.net>
In reply to#8133
Bonjour Christian,

Le 25/11/2025 à 20:45, Christian Weisgerber a écrit :
> On 2025-11-25, Olivier Miakinen <om+news@miakinen.net> wrote:
> 
>> Supposons que j'ai une chaine constituée d'1 ou plusieurs lettres,
>> puis 1 chiffre, puis optionnellement d'autres lettres, puis encore
>> 1 ou plusieurs chiffres. Pour fixer les idées, disons que la chaine
>> répondrait à la regex suivante :
>>    /[a-z]+[0-9][a-z]*[0-9]+/
> 
> En regex basique, c'est
>      /[a-z][a-z]*[0-9][a-z]*[0-9][0-9]*/

Certes. On peut aussi écrire \+ au lieu de + dans les outils tels que
sed. Cela dit, là n'est pas la question : je voulais juste expliquer
de façon condensée la syntaxe simplifiée que je prenais comme exemple.

> S'il y a un caractère qui n'apparait pas dans la chaine,

Héla non. Il y a bien un caractère qui n'apparait pas dans la chaine
à certains endroits dans le cas réel, mais seulement à deux endroits
alors que la chaine doit être coupée en plus de six morceaux.

> on peut
> utiliser un outil externe pour couper la chaine en morceaux, séparer
> les morceaux par ce caractère, et ...

Et donc non, cette méthode ne peut malheureusement pas s'appliquer à
mon cas.

Merci cependant de m'avoir répondu.

Cordialement,
-- 
Olivier

[toc] | [prev] | [next] | [standalone]


#8137

FromChristian Weisgerber <naddy@mips.inka.de>
Date2025-11-25 23:48 +0000
Message-ID<slrn10icg1q.2ald.naddy@lorvorc.mips.inka.de>
In reply to#8135
On 2025-11-25, Olivier Miakinen <om+news@miakinen.net> wrote:

>> S'il y a un caractère qui n'apparait pas dans la chaine,
>
> Héla non. Il y a bien un caractère qui n'apparait pas dans la chaine
> à certains endroits dans le cas réel, mais seulement à deux endroits
> alors que la chaine doit être coupée en plus de six morceaux.

J'imagine que le saut de ligne n'apparait dans la chaine ?

while read -r v1 && read -r v2 && read -r v3 && read -r v4; do
        echo "v1=$v1 v2=$v2 v3=$v3 v4=$v4"
done <<EOF
$(perl -pe 's/([a-z]+)([0-9])([a-z]*)([0-9]+)/$1\n$2\n$3\n$4/')
EOF

-- 
Christian "naddy" Weisgerber                          naddy@mips.inka.de

[toc] | [prev] | [next] | [standalone]


#8138

FromOlivier Miakinen <om+news@miakinen.net>
Date2025-11-26 11:55 +0100
Message-ID<10g6mb9$16sl$1@cabale.usenet-fr.net>
In reply to#8137
Le 26/11/2025 à 00:48, Christian Weisgerber a écrit :
> On 2025-11-25, Olivier Miakinen <om+news@miakinen.net> wrote:
> 
>>> S'il y a un caractère qui n'apparait pas dans la chaine,
>>
>> Héla non. Il y a bien un caractère qui n'apparait pas dans la chaine
>> à certains endroits dans le cas réel, mais seulement à deux endroits
>> alors que la chaine doit être coupée en plus de six morceaux.
> 
> J'imagine que le saut de ligne n'apparait dans la chaine ?

En effet. Même dans le cas réel il n'y a que des lettres (d'ailleurs
majuscules entre A et Z), des chiffres et des tirets.

> while read -r v1 && read -r v2 && read -r v3 && read -r v4; do
>         echo "v1=$v1 v2=$v2 v3=$v3 v4=$v4"
> done <<EOF
> $(perl -pe 's/([a-z]+)([0-9])([a-z]*)([0-9]+)/$1\n$2\n$3\n$4/')
> EOF

C'est presque parfait ! J'ai simplement ajouté un « ^ » et un « $ »
respectivement au début et à la fin de la regex pour m'assurer qu'il
n'y ait pas de caractères parasites au début de v1 ou à la fin de v4.

J'ai quand même deux questions.

D'abord, à quoi sert l'option -p de perl ? D'après les docs que j'ai
lues ça ferait une boucle, mais même sur une seule chaine en entrée
retirer cette option fait que ça ne fonctionne plus.

Par ailleurs, pour le moment cela fonctionne si je passe la chaine
en entrée du script dans stdin, mais je voudrais plutôt que cette
chaine soit une variable dans le script. Comment changer le code
pour cela ?

Je suis désolé si mes questions sont triviales mais hélas je n'ai
jamais pratiqué perl.

Cordialement,
-- 
Olivier Miakinen

[toc] | [prev] | [next] | [standalone]


#8139

FromOlivier Miakinen <om+news@miakinen.net>
Date2025-11-26 12:37 +0100
Message-ID<10g6oq2$22rd$1@cabale.usenet-fr.net>
In reply to#8138
Le 26/11/2025 à 11:55, je répondais à Christian Weisgerber :
> 
>> while read -r v1 && read -r v2 && read -r v3 && read -r v4; do
>>         echo "v1=$v1 v2=$v2 v3=$v3 v4=$v4"
>> done <<EOF
>> $(perl -pe 's/([a-z]+)([0-9])([a-z]*)([0-9]+)/$1\n$2\n$3\n$4/')
>> EOF
> 
> Par ailleurs, pour le moment cela fonctionne si je passe la chaine
> en entrée du script dans stdin, mais je voudrais plutôt que cette
> chaine soit une variable dans le script. Comment changer le code
> pour cela ?

Ok, j'ai trouvé une solution pour cela, et aussi pour pouvoir utiliser
les variables *après* avoir exécuté le code plutôt qu'à l'intérieur du
while, et sans que v1 ne soit écrasée par le dernier tour de boucle :

==================================================================
string=x012

while read -r v1 && read -r v2 && read -r v3 && read -r v4 && \
 read -r junk ; do
        :
done <<EOF
$(echo $string | \
 perl -pe 's/^([a-z]+)([0-9])([a-z]*)([0-9]+)$/$1\n$2\n$3\n$4/')
EOF

echo "v1=$v1 v2=$v2 v3=$v3 v4=$v4"
==================================================================


Est-ce qu'il y aurait une astuce pour éviter d'avoir besoin de la
boucle while ?

[toc] | [prev] | [next] | [standalone]


#8140

FromOlivier Miakinen <om+news@miakinen.net>
Date2025-11-26 13:50 +0100
Message-ID<10g6t2f$n1i$1@cabale.usenet-fr.net>
In reply to#8139
Eurêka !

Le 26/11/2025 à 12:37, j'écrivais :
> 
> Est-ce qu'il y aurait une astuce pour éviter d'avoir besoin de la
> boucle while ?

J'ai trouvé :

IFS=: read v1 v2 v3 v4 <<EOF
$(echo $string | \
	perl -pe 's/^([a-z]+)([0-9])([a-z]*)([0-9]+)$/$1:$2:$3:$4/')
EOF

Il me reste juste à comprendre ce que signifie exactement l'option -p
(ou l'option -n) de perl et pourquoi j'en ai besoin ici.

[toc] | [prev] | [next] | [standalone]


#8143

FromChristian Weisgerber <naddy@mips.inka.de>
Date2025-11-26 21:58 +0000
Message-ID<slrn10ieu08.o9u.naddy@lorvorc.mips.inka.de>
In reply to#8140
On 2025-11-26, Olivier Miakinen <om+news@miakinen.net> wrote:

> J'ai trouvé :
>
> IFS=: read v1 v2 v3 v4 <<EOF
> $(echo $string | \
> 	perl -pe 's/^([a-z]+)([0-9])([a-z]*)([0-9]+)$/$1:$2:$3:$4/')
> EOF

Et là on s'approche de ma première réponse.

Jusqu'ici ces solutions marchent avec quelconque shell POSIX. Mais
si tu utilise le ksh, on peut se servir d'un co-processus.

# lance le co-processus
perl -pe '$|=1; s/^([a-z]+)([0-9])([a-z]*)([0-9]+)$/$1:$2:$3:$4/' |&

# écris la chaine de caractères au co-processus et lis le résultat
print -rp "$string"
IFS=: read -rp v1 v2 v3 v4

# ç'a marché ?
print "v1=$v1 v2=$v2 v3=$v3 v4=$v4"

# le co-processus persiste, on peut lui parler encore
print -rp "$string2"
IFS=: read -rp w1 w2 w3 w4


(« $| = 1 » fait perl écrire une ligne de sortie immédiatement, sans
tampon.)

-- 
Christian "naddy" Weisgerber                          naddy@mips.inka.de

[toc] | [prev] | [next] | [standalone]


#8145

FromOlivier Miakinen <om+news@miakinen.net>
Date2025-11-27 01:09 +0100
Message-ID<10g84rb$2vr6$1@cabale.usenet-fr.net>
In reply to#8143
Le 26/11/2025 à 22:58, Christian Weisgerber a écrit :
> On 2025-11-26, Olivier Miakinen <om+news@miakinen.net> wrote:
> 
>> J'ai trouvé :
>>
>> IFS=: read v1 v2 v3 v4 <<EOF
>> $(echo $string | \
>> 	perl -pe 's/^([a-z]+)([0-9])([a-z]*)([0-9]+)$/$1:$2:$3:$4/')
>> EOF
> 
> Et là on s'approche de ma première réponse.

... première réponse que je n'avais pas comprise, et je te dois des
excuses pour l'avoir écartée à cause de cela avant d'y revenir par
moi-même.

> Jusqu'ici ces solutions marchent avec quelconque shell POSIX. Mais
> si tu utilise le ksh, on peut se servir d'un co-processus.

Hélas c'est une très vieille version du ksh, antérieure à ksh93, et
il y a un certain nombre de syntaxes qui ne fonctionnent pas. Par
exemple celle avec accolades au lieu de parenthèses (que tu donnes
dans ta réponse de 22 h 29) pour éviter de lancer un sous-shell.

> 
> # lance le co-processus
> perl -pe '$|=1; s/^([a-z]+)([0-9])([a-z]*)([0-9]+)$/$1:$2:$3:$4/' |&
> [...]

J'essaierai par curiosité, mais j'ai peu d'espoir que cela fonctionne.

De toute façon, maintenant j'ai grâce à toi fini par obtenir un résultat
très satisfaisant, beaucoup plus lisible et plus court que ce que je
faisais auparavant à base de substitution de variables, alors je vais
me tenir à cette solution.

Encore merci pour tout !

Cordialement,
-- 
Olivier

[toc] | [prev] | [next] | [standalone]


#8148

FromChristian Weisgerber <naddy@mips.inka.de>
Date2025-11-28 15:45 +0000
Message-ID<slrn10ijgta.2otm.naddy@lorvorc.mips.inka.de>
In reply to#8145
On 2025-11-27, Olivier Miakinen <om+news@miakinen.net> wrote:

> Hélas c'est une très vieille version du ksh, antérieure à ksh93, et
> il y a un certain nombre de syntaxes qui ne fonctionnent pas. Par
> exemple celle avec accolades au lieu de parenthèses (que tu donnes
> dans ta réponse de 22 h 29) pour éviter de lancer un sous-shell.

Ça m'étonnerait. As-tu oublié le point-virgule devant l'accolade
fermante ?

> [co-processus]
> J'essaierai par curiosité, mais j'ai peu d'espoir que cela fonctionne.

J'ai verifié que cela fonctionne avec pdksh et ça devrait marcher
avec ksh88 aussi.

-- 
Christian "naddy" Weisgerber                          naddy@mips.inka.de

[toc] | [prev] | [next] | [standalone]


#8150

FromOlivier Miakinen <om+news@miakinen.net>
Date2025-12-08 14:27 +0100
Message-ID<10h6jni$2pb0$2@cabale.usenet-fr.net>
In reply to#8148
Bonjour, et désolé d'avoir mis tant de temps à répondre.

Le 28/11/2025 à 16:45, Christian Weisgerber a écrit :
> 
>> Hélas c'est une très vieille version du ksh, antérieure à ksh93, et
>> il y a un certain nombre de syntaxes qui ne fonctionnent pas. Par
>> exemple celle avec accolades au lieu de parenthèses (que tu donnes
>> dans ta réponse de 22 h 29) pour éviter de lancer un sous-shell.
> 
> Ça m'étonnerait. As-tu oublié le point-virgule devant l'accolade
> fermante ?

Absolument, je n'avais pas imaginé que ce point-virgule soit nécessaire.

>> [co-processus]
>> J'essaierai par curiosité, mais j'ai peu d'espoir que cela fonctionne.
> 
> J'ai verifié que cela fonctionne avec pdksh et ça devrait marcher
> avec ksh88 aussi.

Je te crois. Et finalement je ne vais pas faire l'essai, sauf si tu y
tiens vraiment, parce que d'une part je me satisfais de ma solution
qui marche (avec IFS=":") et que d'autre part l'ordinateur avec Windows
où je pourrais tester est assez éloigné de celui avec Linux qui me sert
à accéder à usenet. À chaque fois je devais m'envoyer des e-mails entre
l'un et l'autre, ou bien écrire sur un bout de papier, pour savoir quel
code je devais tester.

Cordialement,
-- 
Olivier Miakinen

[toc] | [prev] | [next] | [standalone]


#8142

FromChristian Weisgerber <naddy@mips.inka.de>
Date2025-11-26 21:29 +0000
Message-ID<slrn10ies9s.o9u.naddy@lorvorc.mips.inka.de>
In reply to#8139
On 2025-11-26, Olivier Miakinen <om+news@miakinen.net> wrote:

> while read -r v1 && read -r v2 && read -r v3 && read -r v4 && \
>  read -r junk ; do
>         :
> done <<EOF
> $(echo $string | \
>  perl -pe 's/^([a-z]+)([0-9])([a-z]*)([0-9]+)$/$1\n$2\n$3\n$4/')
> EOF
> echo "v1=$v1 v2=$v2 v3=$v3 v4=$v4"

> Est-ce qu'il y aurait une astuce pour éviter d'avoir besoin de la
> boucle while ?

{ read -r v1 && read -r v2 && read -r v3 && read -r v4; } <<EOF
 $(echo "$string" | \
  perl -pe 's/^([a-z]+)([0-9])([a-z]*)([0-9]+)$/$1\n$2\n$3\n$4/')
EOF

-- 
Christian "naddy" Weisgerber                          naddy@mips.inka.de

[toc] | [prev] | [next] | [standalone]


#8141

FromChristian Weisgerber <naddy@mips.inka.de>
Date2025-11-26 21:16 +0000
Message-ID<slrn10iergn.o9u.naddy@lorvorc.mips.inka.de>
In reply to#8138
On 2025-11-26, Olivier Miakinen <om+news@miakinen.net> wrote:

>> while read -r v1 && read -r v2 && read -r v3 && read -r v4; do
>>         echo "v1=$v1 v2=$v2 v3=$v3 v4=$v4"
>> done <<EOF
>> $(perl -pe 's/([a-z]+)([0-9])([a-z]*)([0-9]+)/$1\n$2\n$3\n$4/')
>> EOF
>
> D'abord, à quoi sert l'option -p de perl ? D'après les docs que j'ai
> lues ça ferait une boucle, mais même sur une seule chaine en entrée
> retirer cette option fait que ça ne fonctionne plus.

Cette option permet d'utiliser perl en manière de sed ou awk.
C'est une boucle qui lit d'un fichier ou de l'entrée standard,
exécute les commandes (données par -e) et écrit le résultat à la sortie
standard.

« perl -pe '...' » n'est qu'un raccourcissement de
« perl -e 'while(<>) { ...; print; }' »

> Je suis désolé si mes questions sont triviales mais hélas je n'ai
> jamais pratiqué perl.

J'ai seulement choisi perl parce que insérer \n est plus simple avec
perl qu'avec sed.

-- 
Christian "naddy" Weisgerber                          naddy@mips.inka.de

[toc] | [prev] | [next] | [standalone]


#8144

FromOlivier Miakinen <om+news@miakinen.net>
Date2025-11-27 00:52 +0100
Message-ID<10g83s9$2c3r$1@cabale.usenet-fr.net>
In reply to#8141
Bonjour Christian,

Le 26/11/2025 à 22:16, Christian Weisgerber a écrit :
>>
>> D'abord, à quoi sert l'option -p de perl ? D'après les docs que j'ai
>> lues ça ferait une boucle, mais même sur une seule chaine en entrée
>> retirer cette option fait que ça ne fonctionne plus.
> 
> Cette option permet d'utiliser perl en manière de sed ou awk.
> C'est une boucle qui lit d'un fichier ou de l'entrée standard,
> exécute les commandes (données par -e) et écrit le résultat à la sortie
> standard.
> 
> « perl -pe '...' » n'est qu'un raccourcissement de
> « perl -e 'while(<>) { ...; print; }' »

D'accord, je crois avoir compris pourquoi ça ne fonctionnait pas sans
cela. Ce n'est pas le fait de ne pas faire de boucle (puisque j'ai
une seule entrée, donc une seule ligne), mais le fait qu'il manque
alors le 'print' implicite.

>> Je suis désolé si mes questions sont triviales mais hélas je n'ai
>> jamais pratiqué perl.
> 
> J'ai seulement choisi perl parce que insérer \n est plus simple avec
> perl qu'avec sed.

Oh, ce n'était certainement pas une critique ! Il n'y a pas que le \n
qui est plus simple avec perl qu'avec sed, mais aussi les regex perl
qui sont beaucoup plus faciles à écrire que les regex POSIX. Et puis
elles sont plus complètes, avec par exemple les assertions que j'adore.

-- 
Olivier

[toc] | [prev] | [next] | [standalone]


#8134

FromNicolas George <nicolas$george@salle-s.org>
Date2025-11-25 20:32 +0000
Message-ID<6926124c$0$3355$426a74cc@news.free.fr>
In reply to#8132
Olivier Miakinen , dans le message <10g4rbq$2i1$1@cabale.usenet-fr.net>,
 a écrit :
> Je voudrais extraire chaque partie dans une variable différente.
> Quelques exemples :
>  s="test1xyz27"  ->  v1="test" v2="1"  v3="xyz"  v4="27"
>  s="aa9toto000"  ->  v1="aa"   v2="9"  v3="toto" v4="000"
>  s="x012"        ->  v1="x"    v2="0"  v3=""     v4="12"

En perl, tu mets chaque bout de la regexp qui t'intéresse entre parenthèses
et si ça matche tu récupères la sous-chaîne de chaque groupe entre
parenthèses dans $1, $2, etc. Et tu les récupères aussi comme résultat de la
regexp en contexte liste, donc « my ($x, $y, $t) = /(…)…(…)…(…)/ », que tu
peux d'ailleurs mettre dans la condition d'un if.

(Et si tu as besoin de mettre des parenthèses pour grouper mais que la
sous-chaîne ne t'intéresse pas, tu dois utiliser (?: … ).)

[toc] | [prev] | [next] | [standalone]


#8136

FromOlivier Miakinen <om+news@miakinen.net>
Date2025-11-25 22:42 +0100
Message-ID<10g57s3$20kd$2@cabale.usenet-fr.net>
In reply to#8134
Bonjour Nicolas,

Le 25/11/2025 à 21:32, Nicolas George a écrit :
> Olivier Miakinen , dans le message <10g4rbq$2i1$1@cabale.usenet-fr.net>,
>  a écrit :
>> Je voudrais extraire chaque partie dans une variable différente.
>> Quelques exemples :
>>  s="test1xyz27"  ->  v1="test" v2="1"  v3="xyz"  v4="27"
>>  s="aa9toto000"  ->  v1="aa"   v2="9"  v3="toto" v4="000"
>>  s="x012"        ->  v1="x"    v2="0"  v3=""     v4="12"
> 
> En perl, tu mets chaque bout de la regexp qui t'intéresse entre parenthèses
> et si ça matche tu récupères la sous-chaîne de chaque groupe entre
> parenthèses dans $1, $2, etc. Et tu les récupères aussi comme résultat de la
> regexp en contexte liste, donc « my ($x, $y, $t) = /(…)…(…)…(…)/ », que tu
> peux d'ailleurs mettre dans la condition d'un if.

Ok, mais ce sont des variables du programme perl. Désolé si je n'ai pas
été très clair dans ma demande initiale : je peux utiliser des commandes
perl, awk ou sed dans mon script en korn shell, mais ce sont bien les
variables dans ksh auxquelles je veux pouvoir affecter différentes
parties de la chaine de départ.

Cordialement,
-- 
Olivier

[toc] | [prev] | [next] | [standalone]


#8149

FromChristian Weisgerber <naddy@mips.inka.de>
Date2025-11-28 15:58 +0000
Message-ID<slrn10ijhl8.2otm.naddy@lorvorc.mips.inka.de>
In reply to#8134
On 2025-11-25, Nicolas George <nicolas$george@salle-s.org> wrote:

> En perl, tu mets chaque bout de la regexp qui t'intéresse entre parenthèses
> et si ça matche tu récupères la sous-chaîne de chaque groupe entre
> parenthèses dans $1, $2, etc.

Le problème, c'est récuperer les sous-chaines dans le shell.

C'est possible avec les shells modernes, mais il n'y a pas de
standard. Par exemple, avec bash on peut faire :

if [[ $s =~ ([a-z]+)([0-9])([a-z]*)([0-9]+) ]]; then
        v1=${BASH_REMATCH[1]}
        v2=${BASH_REMATCH[2]}
        v3=${BASH_REMATCH[3]}
        v4=${BASH_REMATCH[4]}
else
        echo "no match"
fi

ksh93 permet le même avec .sh.match en place de BASH_REMATCH.
J'imagine que zsh a une fonctionnalité correspondante.

-- 
Christian "naddy" Weisgerber                          naddy@mips.inka.de

[toc] | [prev] | [next] | [standalone]


#8146

Fromkurtz le pirate <kurtzlepirate@free.fr>
Date2025-11-27 10:59 +0100
Message-ID<10g97eq$ndi$1@rasp.pasdenom.info>
In reply to#8132
On 25/11/2025 19:08, Olivier Miakinen wrote:
> 
> Bonjour,
> 
> Dans un script ksh, je cherche la façon la plus élégante d'extraire
> d'une chaine plusieurs sous-chaines. Le cas réel est plus complexe
> que celui que je vais exposer, mais je saurai extrapoler ensuite.
> 
> 
> Supposons que j'ai une chaine constituée d'1 ou plusieurs lettres,
> puis 1 chiffre, puis optionnellement d'autres lettres, puis encore
> 1 ou plusieurs chiffres. Pour fixer les idées, disons que la chaine
> répondrait à la regex suivante :
>     /[a-z]+[0-9][a-z]*[0-9]+/
> 
> Je voudrais extraire chaque partie dans une variable différente.
> Quelques exemples :
>   s="test1xyz27"  ->  v1="test" v2="1"  v3="xyz"  v4="27"
>   s="aa9toto000"  ->  v1="aa"   v2="9"  v3="toto" v4="000"
>   s="x012"        ->  v1="x"    v2="0"  v3=""     v4="12"
> 
> Bien sûr je sais le faire en autant d'étapes qu'il y a de parties
> à récupérer, en obtenant les variables l'une après l'autre. Mais
> existe-t-il un moyen plus direct ?
>  ...


j'ai fait un test sur <https://www.myregextester.com> avec ces valeurs :

source text : aaaaa111bb22cccccc3333dd44e5f666666
match pattern : ([a-zA-Z]+|\d+)
result : $matches Array:
(
     [0] => Array
         (
             [0] => aaaaa
             [1] => 111
             [2] => bb
             [3] => 22
             [4] => cccccc
             [5] => 3333
             [6] => dd
             [7] => 44
             [8] => e
             [9] => 5
             [10] => f
             [11] => 666666
         )

     [1] => Array
         (
             [0] => aaaaa
             [1] => 111
             [2] => bb
             [3] => 22
             [4] => cccccc
             [5] => 3333
             [6] => dd
             [7] => 44
             [8] => e
             [9] => 5
             [10] => f
             [11] => 666666
         )

)

Avec l'explication :
  ----------------------------------------------------------------------
   (                        group and capture to \1:
----------------------------------------------------------------------
     [a-zA-Z]+                any character of: 'a' to 'z', 'A' to 'Z'
                              (1 or more times (matching the most
                              amount possible))
----------------------------------------------------------------------
    |                        OR
----------------------------------------------------------------------
     \d+                      digits (0-9) (1 or more times (matching
                              the most amount possible))
----------------------------------------------------------------------
   )                        end of \1
----------------------------------------------------------------------
)                        end of grouping
----------------------------------------------------------------------



Ca peut te donner une piste ?
ps : Je n'est pas compris pourquoi il y a deux array (identiques).








-- 
kurtz le pirate
compagnie de la banquise

[toc] | [prev] | [next] | [standalone]


#8147

Fromkurtz le pirate <kurtzlepirate@free.fr>
Date2025-11-27 11:07 +0100
Message-ID<692822e1$0$419$426a34cc@news.free.fr>
In reply to#8132
On 25/11/2025 19:08, Olivier Miakinen wrote:
> [diapublication, suivi vers fr.comp.os.unix seul]
> 
> Bonjour,
> 
> Dans un script ksh, je cherche la façon la plus élégante d'extraire
> d'une chaine plusieurs sous-chaines. Le cas réel est plus complexe
> que celui que je vais exposer, mais je saurai extrapoler ensuite.
> 
> 
> Supposons que j'ai une chaine constituée d'1 ou plusieurs lettres,
> puis 1 chiffre, puis optionnellement d'autres lettres, puis encore
> 1 ou plusieurs chiffres. Pour fixer les idées, disons que la chaine
> répondrait à la regex suivante :
>     /[a-z]+[0-9][a-z]*[0-9]+/
> 
> Je voudrais extraire chaque partie dans une variable différente.
> Quelques exemples :
>   s="test1xyz27"  ->  v1="test" v2="1"  v3="xyz"  v4="27"
>   s="aa9toto000"  ->  v1="aa"   v2="9"  v3="toto" v4="000"
>   s="x012"        ->  v1="x"    v2="0"  v3=""     v4="12"
> 
> ...



Bonjour,

Un test sur <https://www.myregextester.com> avec :

source text : aaaaa111bb22cccccc3333dd44e5f666666
match pattern : ([a-zA-Z]+|\d+)
result : $matches Array:
(
     [0] => Array
         (
             [0] => aaaaa
             [1] => 111
             [2] => bb
             [3] => 22
             [4] => cccccc
             [5] => 3333
             [6] => dd
             [7] => 44
             [8] => e
             [9] => 5
             [10] => f
             [11] => 666666
         )

     [1] => Array
         (
             [0] => aaaaa
             [1] => 111
             [2] => bb
             [3] => 22
             [4] => cccccc
             [5] => 3333
             [6] => dd
             [7] => 44
             [8] => e
             [9] => 5
             [10] => f
             [11] => 666666
         )

)


  NODE                     EXPLANATION
----------------------------------------------------------------------
(?-imsx:                 group, but do not capture (case-sensitive)
                          (with ^ and $ matching normally) (with . not
                          matching \n) (matching whitespace and #
                          normally):
----------------------------------------------------------------------
   (                        group and capture to \1:
----------------------------------------------------------------------
     [a-zA-Z]+                any character of: 'a' to 'z', 'A' to 'Z'
                              (1 or more times (matching the most
                              amount possible))
----------------------------------------------------------------------
    |                        OR
----------------------------------------------------------------------
     \d+                      digits (0-9) (1 or more times (matching
                              the most amount possible))
----------------------------------------------------------------------
   )                        end of \1
----------------------------------------------------------------------
)                        end of grouping
----------------------------------------------------------------------




ca peut te donner une piste ?

ps : je n'arrive pas à poster sur "PasDeNom" bien que test soit ok :(



-- 
kurtz le pirate
compagnie de la banquise

[toc] | [prev] | [next] | [standalone]


#8151

FromDoug713705 <doug.letough@free.fr>
Date2025-12-20 12:30 +0000
Message-ID<slrn10kd5n8.mj.doug.letough@hyperion.local.mcos.nc>
In reply to#8132
Le 25-11-2025, Olivier Miakinen <om+news@miakinen.net> a écrit :
> [diapublication, suivi vers fr.comp.os.unix seul]
>
> Bonjour,

Bonjour,

> Je voudrais extraire chaque partie dans une variable différente.
> Quelques exemples :
>  s="test1xyz27"  ->  v1="test" v2="1"  v3="xyz"  v4="27"
>  s="aa9toto000"  ->  v1="aa"   v2="9"  v3="toto" v4="000"
>  s="x012"        ->  v1="x"    v2="0"  v3=""     v4="12"
>

En python ça donnerait ça:

import re

S = ["test1xyz27", "aa9toto000", "x012"]
pattern = r'([a-z]+)([0-9])([a-z]*)([0-9]+)'
for s in S:
  v1, v2, v3, v4 = re.match(pattern, s).groups()
  print(f"v1: {v1}, v2: {v2}, v3: {v3}, v4: {v4}")


v1: test, v2: 1, v3: xyz, v4: 27
v1: aa, v2: 9, v3: toto, v4: 000
v1: x, v2: 0, v3: , v4: 12


-- 
Doug
Envoyé depuis mon Jacob Delafon 3000 Turbo

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | fr.comp.os.unix


csiph-web