sed, expression reguliere et effectuer une négation

sed, expression reguliere et effectuer une négation - Codes et scripts - Linux et OS Alternatifs

Marsh Posté le 18-03-2010 à 16:15:10    

Je ne connais que peu les expression régulières (oui, je l'utilise en français et je trouve cela bien  :o ) et j'apprend un peu sed, j'ai un besoin de traiter un fichier texte... de 30Mio (!)
 
Je cherche a remplacer chaque occurence de la chaine _[0-9]*_ par [contenu] : ca marche bien avec ceci :

Code :
  1. sed -i 's/_\([0-9]*\)_/[\1]/g'


 
Cependant je voudrais _exclure_ de ces remplacement toutes les chaines potentielles contenant la chaine "input"
J'ai trouvé sur google une méthode pour apparamment rechercher les chaines sauf celles contenant blabla, avec ceci :

Code :
  1. ^((?\!blabla).)*$


 
J'essai donc ceci :  

Code :
  1. sed -e 's/^((?\!input).)*$_\([0-9]*\)_/[\1]/g'


Ca marche ! Sauf que je voudrais plus : éliminer non seulement les chaines contenant input, mais également output. Un truc genre tout sauf les chaines contenant (input OU output)
 
Comment peut-on faire cela ?
Merci !


---------------
Un blog qu'il est bien
Reply

Marsh Posté le 18-03-2010 à 16:15:10   

Reply

Marsh Posté le 18-03-2010 à 16:21:39    

Si tu rajoute en argument un -e avec la même chaîne en remplacant le input par output, ca devrait marcher.

Reply

Marsh Posté le 18-03-2010 à 16:28:08    

je viens de tester et en fait je me trompe :

Code :
  1. 's/^((?\!input).)*$_\([0-9]*\)_/[\1]/g'

ne fait absolument rien, je perd TOUT traitement.
Peut etre que mon not (^) s'applique a toute la chaine ? Avis aux amateurs éclairés  :o


---------------
Un blog qu'il est bien
Reply

Marsh Posté le 18-03-2010 à 17:07:21    

J'avance un peu : plutot que de le faire en une passe, je pense accepter les modifications de la premiere expression, et refaire une passe qui modifierai les chaines mal touchées, surtout que je dois modifier celles-ci d'une autre manière.
 
Exemple d'une ligne avec input (avec N et M des nombres)  :
source : (0) input blablabla_N_M;
transformées après la première expression :  
(1) input blablabla[N][M];  
 
Ce que je veut obtenir :  
(2) input [N:0][M:0] blablabla;
 
A partir de (1), je veut obtenir (2), et ce après cela il me faudra encore d'autres transformations, mais plutot des suppressions de lignes...
Avec l'expression :

Code :
  1. 's/ input *\([0-9]*\)*/ input [\1:0] /g'

j'obtiens :  
(4) input [:0] blablabla[N][M];
 
Suppreimer les derniers crochets est assez facile, un autre sed et hop, par contre je ne voit pas pourquoi ma zone d'intérêt déclarée dans l'expression me renvoi toujours une string vide ?


---------------
Un blog qu'il est bien
Reply

Marsh Posté le 20-03-2010 à 16:31:23    

Voici ce que je te propose :

Code :
  1. awk '!/^input|^output/{print gensub(/_\[([[:digit:]]+)\]_/, "[\\1]", "g" )}'


 
Ca sera plus adapté sur un gros fichier.
 
Pour info ce que tu cherche à faire est un "négative look behind" :
 
Avec un grep compilé avec PCRE, on peux faire ça :

Code :
  1. grep -oP "(?<!input|output)_\K\[[0-9]+."


 
Qu'on peux coder de façon plus fiable en perl :

Code :
  1. perl -lne 'print for /(?<!put)_\K\[[0-9]+./g'

( on retire les lignes qui contiennent put )
 
 
 
Edit, dans ton dernier post, tu a changé les regles en cours de route, maintenant tu veux modifier les chaines contenant input, donc :

Code :
  1. awk '/^input/{print gensub(/(input *[[:alnum:]]+_)([[:digit:]]+)_([[:digit:]]+);/, "\\1[\\2:0]_[\\3:0];", "g" )}'


Message édité par sputnick le 20-03-2010 à 16:45:02
Reply

Sujets relatifs:

Leave a Replay

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