Bidouille avec sed

Bidouille avec sed - Shell/Batch - Programmation

Marsh Posté le 14-01-2005 à 14:31:00    

Bonjour a tous.
 
J'ai un petit souci avec sed...
 
$> cat file
4 clefvaleur
$>
 
En gros le premier chiffre correspond a la taille de 'clef' et 'valeur' est la valeur correspondant a 'clef'. Je veux modifier la ligne pour obtenir "clef=valeur". Pour ce faire, j'utilise 'sed' :
 
$> cat $file | sed -E 's/([0-9]*) (.{\1})(.*)/\2=\3/'
 
ce qui devrait donner le resultat espere. Or ca ne marche pas. Il me sort la ligne telle quel (parce que le pattern ne match pas avec la ligne, sans aucun doute)
 
Voila mon probleme, je ne parviens pas a recuperer le '\1' dans le pattern. Je ne sais pas utiliser 'sed' suffisamment pour trouver une solution, et j'ai pas trouve d'exemples correspondant a mon probleme.
 
Je pense qu'il n'est pas possible d'utiliser '\1' directement dans le pattern, mais je n'ai pas d'autre idee...
 
Quelqu'un a une idee ?
 
Merci

Reply

Marsh Posté le 14-01-2005 à 14:31:00   

Reply

Marsh Posté le 14-01-2005 à 16:04:35    

sed 's/^\([0-9]\) \(.\+\)$/\2=\1/'
 
Edit : le problème classique c'est de ne pas echapper ce qu'il faut, car les caractères à echapper varient d'une commande à l'autre (sed, awk, grep...). Il suffit de faire 2-3 essais simple pour trouver la bonne syntaxe.


Message édité par matafan le 14-01-2005 à 16:06:45
Reply

Marsh Posté le 14-01-2005 à 17:00:40    

Merci pour cette reponse.
 
Non, c'est pas ca le probleme, l'option '-E' (extended regexp, je crois) permet de ne pas avoir le probleme des '\'.
 
De plus, regarde de nouveau mon 1er message, je cherche a utiliser ma premiere capture dans le pattern lui meme, c'est ca le probleme. Je cherche en fait une solution equivalente a ce que j'ai donne dans mon premier message :
 
$> cat $file | sed -E 's/([0-9]*) (.{\1})(.*)/\2=\3/'
 
Je me reexplique. Le format de ma ligne est le suivant :
 
"4 clefvaleur"
 
ou '4' est la longueur de 'clef' et 'valeur' la valeur associee a 'clef'. Je cherche a separer 'clef' et 'valeur' en utilisant la longueur de la clef qui est en debut de ligne. Si 'sed' est capable d'enregistrer une valeur capturee (dans une variable, par exemple) pour l'utiliser soit plus loin dans le commande (un autre 'sed' par exemple), c'est ma solution, mais je ne trouve pas comment faire...
 
Merci encore pour la reponse...
 

Reply

Marsh Posté le 14-01-2005 à 18:43:21    

t'es obligé d'utiliser sed ?

Reply

Marsh Posté le 14-01-2005 à 18:44:29    

En gros oui, j'ai un nombre de commande restreint. Tu pensais a quoi ?


Message édité par arrrrf le 14-01-2005 à 18:45:23
Reply

Marsh Posté le 14-01-2005 à 19:19:51    

A rien en particulier. C'est juste que ça peut être plus simple en perl, python, etc...
 
Je peux pas t'aider avec sed car je n'ai jamais essayé de faire ce que tu dois faire là.
 
 :)

Reply

Marsh Posté le 14-01-2005 à 19:29:31    

Arrrf... Je sais bien... En fait je ne peux utiliser que certaines commandes, et utiliser du perl est bien entendu exclu, au meme titre que le python...
 
Je pensais lancer un autre script shell (vu qu'un banal 'sh' est autorise), lui meme lancant un script perl, mais ca commence a etre n'importe quoi...  :)  
 
Je pensais faire des bidouilles avec 'sed' et le hold space, mais je suis pas encore au top...  ;)  
 
Si quelqu'un sait comment injecter le contenu du hold space dans un pattern, genre :
 
Hold space : 4,
Pattern space : "clefvaleur", et
 
s/(.{hold_space})(.*)/\1=\2/
 
mais voila, je sais ni si c'est possible, ni comment le faire si c'est le cas...
 
Please, help (c)  :)

Reply

Marsh Posté le 14-01-2005 à 20:07:05    

Desole ton message etait clair mais je l'ai lu trop vite.
 
Je ne pense pas que ce soit possible juste avec sed. Je pense que le pattern d'un s/// est focement fixe. Par contre tu peux faire ca avec un peu de shell :

#!/bin/sh
while read line
do
        echo $line | sed 's/^\([0-9]\) \(.\{'${line%% *}'\}\)\(.*\)/\2=\3/'
done


Au fait elle sort d'ou cette option -E de sed ? Le miens ne la reconnait pas (GNU sed version 4.0.9).


Message édité par matafan le 14-01-2005 à 20:14:31
Reply

Marsh Posté le 14-01-2005 à 20:34:08    

Je vais tester ce truc de mon cote, mais si tu pouvais m'expliquer un peu cette commande, ca me plairait, surtout ca :
 

'${line%% *}'


 
Pour ce qui est de l'option '-E' c'est dans une vieille (tres vieille ?) version du 'sed' d'un NetBSD... No comment de ce cote, mais c'est dommage qu'elle ait ete viree cette option, ca clarifie un peu les regexp, n'est ce pas ? :)
 
Je voulais eviter le readline, mais bon, c'est surement la seule solution
 
Merci pour cette reponse. Je repost des que j'ai un resultat.

Edit:

 
Bon, la solution marche, donc c'est plutot cool, merci beaucoup.
Je sais pas pourquoi ca marche par contre... Je peux trouve une explication ou ? man sh ?
 
En tout cas merci !
 
Bonne soiree


Message édité par arrrrf le 14-01-2005 à 22:20:51
Reply

Marsh Posté le 14-01-2005 à 22:54:38    

Ca marche parce que, le ${line%% *} etant en dehors des quotes (je ferme le ' juste avant, et je le reouvre juste apres), il est interprete par le shell. Et en shell ca veut dire "le contenu de line, moins tout ce qui suit le premier espace". Donc finalement si line vaut "4 cleevaleur", ${line%% *} vaut 4 et sed est lance avec en paremetre la chaine "s/^\([0-9]\) \(.\{4\}\)\(.*\)/\2=\3/".


Message édité par matafan le 14-01-2005 à 22:55:12
Reply

Marsh Posté le 14-01-2005 à 22:54:38   

Reply

Marsh Posté le 14-01-2005 à 23:54:29    

Juste comme ca, moi je n'ai pas a faire cette manip (fermer les simples quotes et les rouvrir un peu plus loin), en mettant l'expression entre doubles quote ca marche. Les simples quotes empeche l'evaluation des variables, contrairement aux doubles... Mais bon, c'est peut etre vrai que sur mon archi, comme pour le '-E' de 'sed'...
 
Merci d'avoir eclaire ma lanterne ! ;)
 
Sur ce, bonne nuit.

Reply

Marsh Posté le 15-01-2005 à 02:19:16    

Oui ça marche aussi avec des double quotes sans fermer et réouvrir, mais j'ai préféré la solution avec les simple quotes pour eviter les problèmes si le morceau de sed contient des $.


Message édité par matafan le 15-01-2005 à 02:19:40
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed