[SHELL] remplacer un caractère dans une sous-chaine

Le
zelos 414
Bonjour la liste,


Je me heurte depuis quelques temps à un souci de substitution de
caractère dans une sous-chaine.

Voici la chaîne d'origine:

type[TEST] date[Sun Dec 16 15:45:53 CET 2007] description[permission
denied] level[critical]

Quelquefois, je la reçois sous cette forme (remarquez qu'un espace
s'est inséré dans "perm ission" et "cri tical") :

type[TEST] date[Sun Dec 16 15:45:53 CET 2007] description[perm ission
denied] level[cri tical]

J'aimerai donc supprimer tous les espaces ' ' contenus entre crochets
SAUF dans ceux précédés de 'date' ou 'creationDate'

Je pense que sed peut suffir mais je n'arrive pas à trouver.

En effet:

echo "description[perm ission denied] " | sed -e 's/[.* .*]/[.*_.*]/g=
'

et

tr ' ' '_'

ne sont pas corrects.

Auriez-vous une idée?

Merci.

Zelos
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
zelos 414
Le #9635701
Le 20/12/07, Guillaume Coeugnet
> -----Message d'origine-----
> De : zelos 414 [mailto:]
> Envoyé : jeudi 20 décembre 2007 11:02
> À : Debianfr List
> Objet : [SHELL] remplacer un caractère dans une sous-chaine
>
> Bonjour la liste,
>
>
> Je me heurte depuis quelques temps à un souci de substitution
> de caractère dans une sous-chaine.
>
> Voici la chaîne d'origine:
>
> type[TEST] date[Sun Dec 16 15:45:53 CET 2007]
> description[permission denied] level[critical]
>
> Quelquefois, je la reçois sous cette forme (remarquez qu'un
> espace s'est inséré dans "perm ission" et "cri tical") :
>
> type[TEST] date[Sun Dec 16 15:45:53 CET 2007]
> description[perm ission denied] level[cri tical]
>
> J'aimerai donc supprimer tous les espaces ' ' contenus entre
> crochets SAUF dans ceux précédés de 'date' ou 'creationDate'
>
> Je pense que sed peut suffir mais je n'arrive pas à trouver.
>
> En effet:
>
> echo "description[perm ission denied] " | sed -e 's/[.*
> .*]/[.*_.*]/g'
>
> et
>
> tr ' ' '_'
>
> ne sont pas corrects.
>
> Auriez-vous une idée?
>
> Merci.
>
> Zelos
>
>

Pourquoi n'utilises tu pas un outil comme le perl qui est fait pour trait er
des chaines de caractère ?





Je ne connais pas perl et tout le reste du script est en shell...
Daniel Caillibaud
Le #9635691
zelos 414 a écrit :
echo "description[perm ission denied] " | sed -e 's/[.* .*]/[.*_.*]/g'



Tu ne peux pas mettre de .* dans la chaine de substitution, tu dois utiliser les références arrières

echo "description[perm ission denied] " | sed -e 's/[(.*) (.*)]/[1_2]/g'

marchera mieux (un peu, car ça ne substitue que la derniere espace située entre crochet, le .* est gourmand).

tr ' ' '_'



echo "description[perm ission denied] " | tr ' ' '_'

marche très bien, mais tu n'as pas de regexp pour trier tes espaces à substituer.

--
Daniel


--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.net/?DebianFrench
Vous pouvez aussi ajouter le mot ``spam'' dans vos champs "From" et
"Reply-To:"

To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact
fra-duf-no-spam
Le #9635671
Le 13867ième jour après Epoch,
Daniel Caillibaud écrivait:

zelos 414 a écrit :
echo "description[perm ission denied] " | sed -e 's/[.* .*]/[.*_.* ]/g'



Tu ne peux pas mettre de .* dans la chaine de substitution, tu dois utili ser les références arrières

echo "description[perm ission denied] " | sed -e 's/[(.*) (.*)]/[1 _2]/g'

marchera mieux (un peu, car ça ne substitue que la derniere espace
située entre crochet, le .* est gourmand).



On peut diminuer sa "cupidité" en rajoutant un '?' après... Ce qui
donnerait .*? mais qui ne marche pas chez moi :(
Sylvain Sauvage
Le #9635661
zelos 414, jeudi 20 décembre 2007, 11:02:21 CET

Bonjour la liste,



’jour,

Je me heurte depuis quelques temps à un souci de substitution
de caractère dans une sous-chaine.

Voici la chaîne d'origine:

type[TEST] date[Sun Dec 16 15:45:53 CET 2007]
description[permission denied] level[critical]

Quelquefois, je la reçois sous cette forme (remarquez qu'un
espace s'est inséré dans "perm ission" et "cri tical") :

type[TEST] date[Sun Dec 16 15:45:53 CET 2007] description[perm
ission denied] level[cri tical]

J'aimerai donc supprimer tous les espaces ' ' contenus entre
crochets SAUF dans ceux précédés de 'date' ou 'creationDat e'



Je suppose que les espaces insérés ne sont pas toujours au
même endroit (sinon ce serait trop simple).

Je pense que sed peut suffir mais je n'arrive pas à trouver.

En effet:

echo "description[perm ission denied] " | sed -e
's/[.* .*]/[.*_.*]/g'

et

tr ' ' '_'

ne sont pas corrects.

Auriez-vous une idée?



La commande « s » prend une ou deux « adres ses » :
adr1,adr2 s/…/…/…
Ces adresses indiquent à s le cadre dans lequel il doit
opérer. Ce sont deux expressions régulières marquant la zone
de texte (une seule adresse → toute la ligne, deux adresses
→ début et fin de zone).

Donc, pour remplacer tous les espaces entre deux crochets :
/[/,/]/s/ /_/g

À noter que, puisqu’il s’agit de remplacer un seul c aractère,
la commande « y » suffit ;
/[/,/]/y/ /_/

Bon, ça remplace tous les espaces mais ça le fait aussi pour
date et creationDate, il faut donc discriminer. Et c’est là que
les Athéniens s’atteignirent, la négation est une plaie :

/([^Dd]...|[dD]([^a]..|a([^t].|t[^e])))[/,/]/y/ /_/

en clair, on teste les quatre caractères avant le crochet :
— soit ce n’est pas d (ou D) ;
— soit c’est d (ou D) et,
— pas suivi d’un a ;
— suivi d’un a et,
— pas suivi d’un t ;
— suivi d’un t mais pas d’un e.

(Merci tous les à mettre devant les () et les |…
Encore heureux que « xxx|yyy » n’a pas besoin d’être écrit
« (xxx)|(yyy) »…)

Bon, là ça ne teste que [Dd]ate, tu pourras facilement
généraliser.

Ah, euh, il ne faut pas de [] emboîtés dans les []…

--
Sylvain Sauvage
Vincent Lefevre
Le #9635651
On 2007-12-20 13:55:59 +0100, François TOURDE wrote:
Le 13867ième jour après Epoch,
Daniel Caillibaud écrivait:
> marchera mieux (un peu, car ça ne substitue que la derniere espace
> située entre crochet, le .* est gourmand).

On peut diminuer sa "cupidité" en rajoutant un '?' après... Ce qui
donnerait .*? mais qui ne marche pas chez moi :(



Je ne pense pas que ce soit standard. C'est une extension dans
les regexp de Perl (et tout ce qui les utilise), non?

--
Vincent Lefèvre 100% accessible validated (X)HTML - Blog: Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)


--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.net/?DebianFrench
Vous pouvez aussi ajouter le mot ``spam'' dans vos champs "From" et
"Reply-To:"

To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact
fra-duf-no-spam
Le #9635641
Le 13867ième jour après Epoch,
Vincent Lefevre écrivait:

On 2007-12-20 13:55:59 +0100, François TOURDE wrote:


[...]
On peut diminuer sa "cupidité" en rajoutant un '?' après... Ce qui
donnerait .*? mais qui ne marche pas chez moi :(



Je ne pense pas que ce soit standard. C'est une extension dans
les regexp de Perl (et tout ce qui les utilise), non?



Très juste. Désolé pour le bruit.
Sylvain Sauvage
Le #9635631
Sylvain Sauvage, jeudi 20 décembre 2007, 16:04:19 CET
[…]
La commande « s » prend une ou deux « adr esses » :
adr1,adr2 s/…/…/…
Ces adresses indiquent à s le cadre dans lequel il doit
opérer. Ce sont deux expressions régulières marquant la zo ne
de texte (une seule adresse → toute la ligne, deux adresses
→ début et fin de zone).



Bon, je raconte n’importe quoi !
Pour sed, les adresses ne fonctionnent que sur plusieurs
lignes.

[…]



En revanche, la négation :

/([^Dd]...|[dD]([^a]..|a([^t].|t[^e])))[/,/]/y/ /_/

en clair, on teste les quatre caractères avant le crochet :
— soit ce n’est pas d (ou D) ;
— soit c’est d (ou D) et,
— pas suivi d’un a ;
— suivi d’un a et,
— pas suivi d’un t ;
— suivi d’un t mais pas d’un e.

(Merci tous les à mettre devant les () et les |…
Encore heureux que « xxx|yyy » n’a pas besoi n d’être écrit
« (xxx)|(yyy) »…)

Bon, là ça ne teste que [Dd]ate, tu pourras facilement
généraliser.



… peut toujours servir.

Mais ça devient très lourd à gérer avec sed. Il vaudr ait
vraiment passer à un vrai langage (Ruby, Perl…).

Pour me pardonner d’avoir dit une ânerie :

#!/usr/bin/ruby
while ligne = STDIN.gets
crochet = false
until ligne.nil?
case ligne
when /A[dD]ate[/
print $&
when /A[/
crochet = true
print $&
when /A]/
crochet = false
print $&
when /A /
if crochet
print '_'
else
print ' '
end
when /A./
print $&
end
ligne = $'
end
print "n"
end

(on peut faire plus court mais j’ai fait lisible…)
Le principe est de manger la ligne petit bout par petit bout
(le A indique « début de la chaîne »).
$& contient la correspondance de la regexp
$' contient le reste de la chaîne

--
Sylvain Sauvage
Jean-Michel OLTRA
Le #9635621
Bonjour,


Le jeudi 20 décembre 2007, zelos 414 a écrit...


Je pense que sed peut suffir mais je n'arrive pas à trouver.



En effet:



echo "description[perm ission denied] " | sed -e 's/[.* .*]/[.*_.*]/g'



Auriez-vous une idée?



Avec ssed, car ssed accepte le lookbehind :

echo "description[perm ission denied] " | ssed -R '/(?<!ate)[/{s/ //}'

Bon, ça marche dans ce cas là, si j'ai bien compris la problématique,
mais il faut voir si tu peux le généraliser.

--
jm

A.E.L. Sarl (R.C.S CASTRES 490843240)
http://www.spidboutic.fr



--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.net/?DebianFrench
Vous pouvez aussi ajouter le mot ``spam'' dans vos champs "From" et
"Reply-To:"

To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact
Daniel Caillibaud
Le #9635571
Sylvain Sauvage a écrit :
Donc, pour remplacer tous les espaces entre deux crochets :
/[/,/]/s/ /_/g



Ça va remplacer toutes les espaces des lignes comprises une ligne contenant un crochet ouvrant et la premières des
lignes suivantes qui contient un crochet fermant (ces deux lignes qui "matchent" la sélection sont inclusent).

--
Daniel


--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.net/?DebianFrench
Vous pouvez aussi ajouter le mot ``spam'' dans vos champs "From" et
"Reply-To:"

To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact
Davy Gigan
Le #9635551
--nextPart6104950.rmogpK1RU3
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Le jeudi 20 décembre 2007 11:02, zelos 414 a écrit :
Bonjour la liste,


Je me heurte depuis quelques temps à un souci de substitution de
caractère dans une sous-chaine.

Voici la chaîne d'origine:

type[TEST] date[Sun Dec 16 15:45:53 CET 2007] description[permission
denied] level[critical]

Quelquefois, je la reçois sous cette forme (remarquez qu'un espace
s'est inséré dans "perm ission" et "cri tical") :

type[TEST] date[Sun Dec 16 15:45:53 CET 2007] description[perm ission
denied] level[cri tical]

J'aimerai donc supprimer tous les espaces ' ' contenus entre crochets
SAUF dans ceux précédés de 'date' ou 'creationDate'



Désolé, je ne répondrai pas vraiment à ta question mais corriger le problème à
sa source est-il envisageable ?

As-tu regardé pourquoi tu obtiens des espaces « en trop » dans tes ch aines ?

D'autre part, tu ne devrais pas remplacer tous les espaces dans "perm issio n
denied" ...


--
Davy Gigan
System & Network Administration [Please no HTML, I'm not a browser]
University Of Caen (France) [Pas d'HTML, je ne suis pas un navigateur]

--nextPart6104950.rmogpK1RU3
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQBHarC7kbS8+CLlzYgRAmqdAJ9hVBwFqw9OtSR9fw5Be4XwVkSEtgCfdBdp
hMol7FRDnxKBIuM2wEZ5y0M =hmD0
-----END PGP SIGNATURE-----

--nextPart6104950.rmogpK1RU3--


--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.net/?DebianFrench
Vous pouvez aussi ajouter le mot ``spam'' dans vos champs "From" et
"Reply-To:"

To UNSUBSCRIBE, email to
with a subject of "unsubscribe". Trouble? Contact
Publicité
Poster une réponse
Anonyme