Précédent   Forum des professionnels en informatique > Systèmes > Linux > Applications
Applications Questions sur l'utilisation d'applications, du shell, et des interfaces graphiques (KDE, Gnome, XFCE... )
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 10/03/2011, 11h02   #1
Membre confirmé
 
Inscription : avril 2008
Messages : 187
Détails du profil
Informations forums :
Inscription : avril 2008
Messages : 187
Points : 221
Points : 221
Par défaut sed - référencer une sous-expression

Bonjour,

Voici un exemple de ce que je voudrais faire. C'est un exemple simplifié pour faciliter la compréhension. En réalité "a" "b" et "c" sont plus compliqués.


Dans chaque ligne contenant "a" suivi de "b" suivi de "c", je voudrais remplacer le "b" par "B":

Code :
1
2
# echo "abc" | sed -e '/a\(b\)c/ s/\1/B/'
sed: -e expression #1, char 17: Invalid back reference
Comme "a" ou "c" peuvent contenir "b", il est exclu de faire un simple "s/b/B".

Suis-je contraint à faire ceci:

Code :
1
2
# echo "abc" | sed -e '/abc/ s/\(a\)b\(c\)/\1B\2/'
aBc
où, du coup, je peux laisser tomber le /abc/:

Code :
1
2
# echo "abc" | sed -e 's/\(a\)b\(c\)/\1B\2/'
aBc

Comme "a" "b" et "c" sont plutôt longs, la première écriture, étant plus compacte et plus lisible (moins de parenthèses et de backslashes), aurait eu ma préférence... s'il y avait moyen de la faire marcher!

Any suggestion ou confirmation?

Merci d'avance

)jack(
jack-ft est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 10/03/2011, 11h13   #2
Expert Confirmé Sénior
 
Avatar de frp31
 
Homme francois
Ingénieur systèmes et réseaux
Inscription : juillet 2006
Messages : 3 534
Détails du profil
Informations personnelles :
Nom : Homme francois
Âge : 35
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur systèmes et réseaux
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : juillet 2006
Messages : 3 534
Points : 7 743
Points : 7 743
aucun intêret d'utiliser la sous-expression dans ce cas.

suffit

imaginons que tu veuilles faire un

xxxxxxxxxYYYYYYYYyYYYYYzzzzzzzzzzz
et convertir le y en Y

Code :
1
2
3
$ sed "s/y/Y/g" fichier
xxxxxxxxxYYYYYYYYYYYYYYzzzzzzzzzzz
$
l'interêt serait plustot de modifier l'ordre, là oui tu as besoin d'une sous exp
Code :
1
2
3
4
 
$ sed "s/\(x.*x\)\(Y.*Y\)/\2\1/" fichier
YYYYYYYYyYYYYYxxxxxxxxxzzzzzzzzzzz
$


je te conseilles ce site sur sed :
http://sed.sourceforge.net/sed1line.txt

extrêmement puissant et formateur par l'exemple
frp31 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/03/2011, 11h17   #3
Membre Expert
 
Homme Alexis
Intégrateur d'Exploitation
Inscription : février 2003
Messages : 876
Détails du profil
Informations personnelles :
Nom : Homme Alexis
Âge : 32
Localisation : France

Informations professionnelles :
Activité : Intégrateur d'Exploitation
Secteur : Biens de consommation

Informations forums :
Inscription : février 2003
Messages : 876
Points : 1 619
Points : 1 619
Envoyer un message via ICQ à Alek-C Envoyer un message via Skype™ à Alek-C
Si c'est dans un script, pourquoi ne pas utiliser des variables ? Ca simplifiera la lecture et la maintenance

Code :
1
2
3
$ export pre=tatoti
$ export post=tutote
$ echo "tatotitotutote" | sed "s/${pre}to$post/${pre}TO$post/"

@frp31: ça ne marche pas car a et c peuvent contenir b.

Par exemple, a=tatoti, b=to et c=tutote

Si tu fais echo tatotitotutote | sed "s/to/TO/g", tu remplaces forcément le to de a et de c par TO ce que ne veut pas faire jack-ft

Les références arrières sont uniquement là pour éviter d'écrire un truc comme echo tatotitotutote | sed "s/tatotitotutote/tatotiTOtutote/g" ce qui peut devenir long à lire... alors qu'avec les références, tu peux gagner un peu : echo tatotitotutote | sed "s/\(tatoti\)to\(tutote\)/\1TO\2/g" (bon, c'est useless ici car les 2 font la même longueur, mais si au lieu de tatoti tu as tatotitatotitatotitatotitatotitatotitatotitatotitatotitatoti, ça permet de gagner quelques caractères... mais ça reste illisible, alors qu'avec 2 jolies variables :p
Alek-C est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 10/03/2011, 12h26   #4
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
Salut,

Et comme ça :

Code :
1
2
$ echo "cbaabcbaba" | sed  '/abc/ s/a\(b\)c/\U\1/'
cbaBbaba


Edit : Remplacement de "\u" par "\U" vu que c'est pour plusieurs caractères et non pour un unique caractère
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est actuellement connecté   Envoyer un message privé Réponse avec citation 20
Vieux 10/03/2011, 13h50   #5
Membre Expert
 
Homme Alexis
Intégrateur d'Exploitation
Inscription : février 2003
Messages : 876
Détails du profil
Informations personnelles :
Nom : Homme Alexis
Âge : 32
Localisation : France

Informations professionnelles :
Activité : Intégrateur d'Exploitation
Secteur : Biens de consommation

Informations forums :
Inscription : février 2003
Messages : 876
Points : 1 619
Points : 1 619
Envoyer un message via ICQ à Alek-C Envoyer un message via Skype™ à Alek-C
Ça, ça ne marche pas si j'ai bien compris le problème

Le problème tel que je l'ai compris :

Voici un texte :
Code :
1
2
3
4
$ cat test
<a href="autrepart.html>autrepart</a>
<a href="quelquepart.html">autrepart</a>
<a href="quelquepart.html">autrepart dans quelque part</a>
On veut changer le second lien autrepart par quelquepart... mais pas toucher au premier bien sûr.

du coup, on pourrait faire :
Code :
1
2
3
4
$ sed -e 's/\(<a href="quelquepart.html">\)autrepart\(<\/a>\)/\1quelquepart\2/' test
<a href="autrepart.html>autrepart</a>
<a href="quelquepart.html">quelquepart</a>
<a href="quelquepart.html">autrepart dans quelque part</a>
Mais c'est un peu pénible à lire.
En utilisant des variables:
Code :
1
2
3
4
5
6
$ export pre="<a href=\"quelquepart.html\">"
$ export post="<\/a>"
$ sed -e 's/${pre}autrepart${post}/${pre}quelquepart${post}/' test
<a href="autrepart.html>autrepart</a>
<a href="quelquepart.html">autrepart</a>
<a href="quelquepart.html">autrepart dans quelque part</a>
Ca n'est pas génial non plus, mais je trouve que c'est un peu plus lisible...

Sinon, avec perl et les recherches avant/arrières :
Code :
1
2
3
4
$ perl -n -e 's/(?<=<a href=\"quelquepart.html\">)autrepart(?=<\/a>)/quelquepart/ ; print' test
<a href="autrepart.html>autrepart</a>
<a href="quelquepart.html">quelquepart</a>
<a href="quelquepart.html">autrepart dans quelque part</a>
Remplace toutes les occurences de autrepart précédées de <a href="quelquepart.html"> et suivies de </a> par quelquepart.

Les symboles (?<= ... ) et (?= ... ) indique que le motif doit être respectivement avant et après ce que l'on cherche, mais ne sont pas dans la capture...
Alek-C est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 10/03/2011, 14h35   #6
Membre confirmé
 
Inscription : avril 2008
Messages : 187
Détails du profil
Informations forums :
Inscription : avril 2008
Messages : 187
Points : 221
Points : 221
Citation:
Envoyé par Alek-C Voir le message
@frp31: ça ne marche pas car a et c peuvent contenir b.
Farpaitement!

Et je suis désolé d'avoir utilisé "B" plutôt que "d" car j'ai enduit d'erreur (sic!) ceux qui ont cru à une capitalisation alors que "d" est indépendant de "b"

Citation:
Ça, ça ne marche pas si j'ai bien compris le problème
Tu as tout à fait compris le problème: et, en fait, les parties "a" et "b" sont effectivement des balises xml!

Citation:
Sinon, avec perl et les recherches avant/arrières :
Code :
1
2
3
4
$ perl -n -e 's/(?<=<a href=\"quelquepart.html\">)autrepart(?=<\/a>)/quelquepart/ ; print' test
<a href="autrepart.html>autrepart</a>
<a href="quelquepart.html">quelquepart</a>
<a href="quelquepart.html">autrepart dans quelque part</a>
Remplace toutes les occurences de autrepart précédées de <a href="quelquepart.html"> et suivies de </a> par quelquepart.

Les symboles (?<= ... ) et (?= ... ) indique que le motif doit être respectivement avant et après ce que l'on cherche, mais ne sont pas dans la capture...
C'est exactement ce que je voulais: le motif recherché précédé et suivi des balises, mais non compris dans la capture.

Je crois que je vais rester avec sed et prendre la solution avec les variables.

Merci à tous d'avoir contribué

)jack(
jack-ft est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 10/03/2011, 15h11   #7
Membre Expert
 
Homme Alexis
Intégrateur d'Exploitation
Inscription : février 2003
Messages : 876
Détails du profil
Informations personnelles :
Nom : Homme Alexis
Âge : 32
Localisation : France

Informations professionnelles :
Activité : Intégrateur d'Exploitation
Secteur : Biens de consommation

Informations forums :
Inscription : février 2003
Messages : 876
Points : 1 619
Points : 1 619
Envoyer un message via ICQ à Alek-C Envoyer un message via Skype™ à Alek-C
Je ne crois pas que sed gère les références arrières
Alek-C est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 10/03/2011, 15h33   #8
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
Citation:
Envoyé par Alek-C Voir le message
Je ne crois pas que sed gère les références arrières
Si si à sa façon

En me servant de ton fichier d'exemple et de tes variables :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ pre="<a href=\"quelquepart.html\">"
$ post="<\/a>"
$ motif="autrepart"

$ cat plop
<a href="autrepart.html>autrepart</a>
<a href="quelquepart.html">autrepart</a>
<a href="quelquepart.html">autrepart dans quelque part</a>

$ sed "s/\(${pre}\)\(${motif}\)\(${post}\)/\1\U\2\3/" plop
<a href="autrepart.html>autrepart</a>
<a href="quelquepart.html">AUTREPART</A>
<a href="quelquepart.html">autrepart dans quelque part</a>
$
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est actuellement connecté   Envoyer un message privé Réponse avec citation 20
Vieux 10/03/2011, 15h59   #9
Membre Expert
 
Homme Alexis
Intégrateur d'Exploitation
Inscription : février 2003
Messages : 876
Détails du profil
Informations personnelles :
Nom : Homme Alexis
Âge : 32
Localisation : France

Informations professionnelles :
Activité : Intégrateur d'Exploitation
Secteur : Biens de consommation

Informations forums :
Inscription : février 2003
Messages : 876
Points : 1 619
Points : 1 619
Envoyer un message via ICQ à Alek-C Envoyer un message via Skype™ à Alek-C
Je me suis trompé de terme... je voulais parler des assertions arrières/avant
Alek-C est déconnecté   Envoyer un message privé Réponse avec citation 11
Vieux 10/03/2011, 16h32   #10
Membre confirmé
 
Inscription : avril 2008
Messages : 187
Détails du profil
Informations forums :
Inscription : avril 2008
Messages : 187
Points : 221
Points : 221
Citation:
Envoyé par zipe31 Voir le message
Si si à sa façon

En me servant de ton fichier d'exemple et de tes variables :
Oui. C'est exactement ce que je voulais dire (sauf que c'est pas du \U):

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ pre="<a href=\"quelquepart.html\">"
$ post="<\/a>"
$ motif="autrepart"
$ new_motif="ailleurs"

$ cat plop
<a href="autrepart.html>autrepart</a>
<a href="quelquepart.html">autrepart</a>
<a href="quelquepart.html">autrepart dans quelque part</a>

$ sed "s/\(${pre}\)${motif}\(${post}\)/\1${new_motif}\2/" plop
<a href="autrepart.html>autrepart</a>
<a href="quelquepart.html">ailleurs</A>
<a href="quelquepart.html">autrepart dans quelque part</a>
$
Encore merci

)jack(
jack-ft est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 10/03/2011, 16h35   #11
Expert Confirmé Sénior
 
Avatar de frp31
 
Homme francois
Ingénieur systèmes et réseaux
Inscription : juillet 2006
Messages : 3 534
Détails du profil
Informations personnelles :
Nom : Homme francois
Âge : 35
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur systèmes et réseaux
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : juillet 2006
Messages : 3 534
Points : 7 743
Points : 7 743
bien vu cette solution est propre. je me la note dans un canard ... heu un coin ...
frp31 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/03/2011, 16h36   #12
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
Citation:
Envoyé par jack-ft Voir le message
Oui. C'est exactement ce que je voulais dire (sauf que c'est pas du \U):
je voudrais remplacer le "b" par "B"
Ah ben moi je suis bête et discipliné, mais plus bête que discipliné
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est actuellement connecté   Envoyer un message privé Réponse avec citation 10
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 18h31.


 
 
 
 
Partenaires

Hébergement Web