Test sur chaine de caractere éditeur vi

Résolu/Fermé
ronan - 7 déc. 2012 à 10:50
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 - 7 déc. 2012 à 18:18
Bonjour,

Savez-vous s'il est possible dans l'éditeur vi de rechercher une chaine de caractere précise et lorsque cette chaine est trouvée, d'effectuer une substitution ? Il y a une astuce cependant.

Je m'explique. J'ai un code dont j'aimerais modifier certaines lignes seulement. Exemple, j'aimerais modifier les lignes contenant l'expression :
" ... arg + = ..."
par l'expression :
" ... arg + = list( ... )"

Je conviens que le rajout de la chaine " list(" ne pose pas de problème. Mais au contraire, l'ajout de la parenthèse finale, en fin de ligne, seulement dans le cas où la chaine "arg + =" est présente me pose un soucis. De plus, ce qui doit se trouver entre les parenthèses list(...) est de forme et de longueur totalement aléatoire.

Auriez-ous une idée ?

Je vous remercie.


Cdlt


Ronan.

A voir également:

6 réponses

zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 407
7 déc. 2012 à 10:59
Salut,

"arg" c'est du littéral ou c'est variable ?

T'aurais un exemple concret s'il te plaît ?
0
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 7 748
7 déc. 2012 à 11:06
Je ne sais pas si ça répond à la question car comme le souligne zipe31 la question mérite quelques précisions, mais si j'ai bien compris, appuie sur echap et tape :

:%s/arg + = \(.*\)/arg + = list(\1)/gc


Le "c" terminal fera qu'une confirmation sera demandée par vim à chaque occurrence la confirmation (y/n).

Bonne chance
0
Bonjour,

Super ! Je vous remercie pour vos réponses. mamiemando, pourriez-vous m'expliquer la signification des commandes comme (.*\) et (\1) ?

Alors l'exemple concret c'est que par exemple, j'applique une formule avec la variable "arg" quelconque.
Il y a différents calculs et chaque ligne de "arg + =" est unique.

exemple :

quelque chose arg + = quelque chose
et je voudrais obtenir
quelque chose arg + = list( quelque chose )

Le probleme est donc de rajouter le ")" a la fin de la ligne contenant un "arg + =", puisque les chaines identifiées par "quelque chose" sont totalement différentes les unes des autres.
Mon probleme étant justement de demander le remplacement de "$" c'est a dire la fin de ligne par un ")" seulement lorsque la ligne contient un "arg + =".

Mamiemando, je vais tester votre solution, je reviens vers vous dès que possible.

Merci du coup de main !


Ronan.
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 407
7 déc. 2012 à 11:44
Ok. Donc la commande de mamiemando légèrement remaniée devrait faire l'affaire :

:%s/+ = \(.*\)/+ = list( \1 )/gc


Pour les explications :

\(.*\)
Est ce qu'on appelle un référence arrière.
Autrement dit, on capture un motif, ici représenté par ".*" (dans ton exemple tout ce qui se trouve après l'espace derrière le signe égale jusqu'à la fin de la ligne), à l'aide de parenthèses (que l'on protège avec un anti-slash).

\1
Représente la 1ère référence arrière que l'on veut rappeler.
S'il y en avait plusieurs, on les appellerait par leur ordre d'apparition (\2, \3, etc. jusqu'à 9).
Donc dans ton exemple on remet le contenu de la référence arrière en l'entourant avec des parenthèses "( \1 )".
0
Ah vraiment les amis, merci beaucoup c'est super ! Ca marche nickel et j'ai appris un nouveau truc sur la puissance de vi !

Merci !

Autrement, pour pousser le vice un peu plus loin, imaginez que ce genre de ligne à changer existe dans plusieurs fichiers.
Connaitriez vous un moyen (shell par exemple ?) de mettre une commande récursive, qu'elle aille voir dans tous les fichiers et qu'elle interprete la commande vi mentionnée plus haut ?

Je ne sais pas s'il est possible de faire executer une commande vi par un shell.
A moins de modifier le .vimrc

A votre avis ?
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 407
7 déc. 2012 à 11:56
Avec "sed" :

sed -i.bak  's/+ = \(.*\)/+ = list( \1 )/' *.txt


L'option "-i" permet de modifier chaque fichier directement.
Le ".bak" permet de faire une copie de sauvegarde de chaque fichier (c'est facultatif).
L'extension à la fin (*.txt) permet de cibler que les fichiers .txt, à adapter. Par contre ce n'est pas récursif.

Par mesure de sécurité, essaye d'abord la commande sur un ou deux fichiers de test, hein ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
mamiemando Messages postés 33077 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2024 7 748
Modifié par mamiemando le 7/12/2012 à 13:07
Comme dit zipe31 c'est effectivement plus logique d'utiliser sed, mais il me semble tu peux aussi passer par vim. Étant donné que sed suffit autant utiliser sed (d'autant que la syntaxe de substition est la même dans vim et dans sed).

Pour des cas plus compliqués, on utiliserait plutôt un langage de script comme awk, et pour des cas encore plus extrêmes des langages plus évolués comme python, perl ou ruby.

Est-ce que ton problème est résolu ?

Bonne chance
0
C'est parfait !

Merci beaucoup pour votre aide !

J'ai beaucoup apprécié cet échange. J'ai appris plein de trucs grace à vous.

Bon week end à tous !


Ronan.
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 407
7 déc. 2012 à 18:18
De rien.

Bon week-end à toi aussi ;-)
0