2013-05-21 3 views
0

J'ai un grand nombre de fichiers et je souhaite remplacer certaines lignes de tous ces fichiers. Je ne connais pas le contenu exact des lignes, tout ce que je sais, c'est qu'elles contiennent deux mots connus - disons, par exemple, 'Programmer' et 'Bob'. Ainsi, les lignes que je veux remplacer pourrait être quelque chose comme:Remplacement d'une ligne de plusieurs fichiers, limitation à une plage de numéros de ligne

Created by Programmer Bob 
Programmer extraordinaire Bob, such an awesome guy 
Copyright programmer bob, all rights reserved 

Jusqu'à présent, cela semble facile, mais le problème est que je ne veux que de remplacer les lignes qui sont contenues dans une plage de ligne - par exemple au début de le fichier (où généralement on trouverait des commentaires concernant le fichier). Je ne peux pas remplacer les lignes trouvées dans les dernières parties du fichier, car je ne veux pas remplacer accidentellement le code réel.

Jusqu'à présent, j'ai essayé:

find . -exec grep -il -E 'Programmer.*Bob' {} \; | xargs sed -i '1,10 /Programmer.*Bob/Ic\LINE REPLACED' 

(J'utilise trouver parce que grep a couru dans une récursion infinie - Je ne pense pas le point ici..)

Cependant, il semble que je peux n'utilisez pas les plages d'adresses avec c \ (ligne de changement). N'hésitez pas à signaler les erreurs de syntaxe, mais je pense que j'ai tout essayé en vain. Cela fonctionne sans les numéros de ligne.

EDIT: J'ai obtenu la réponse, mais j'ai décidé d'éditer ma question pour inclure ma solution qui étend sur la réponse que j'ai - peut-être que quelqu'un trouvera ceci utile.

Je me suis rendu compte plus tard que je souhaitais conserver les espaces blancs et les caractères de commentaire possibles au début de la ligne. Je l'ai accompli en utilisant cette commande:

find . -exec grep -ilI '.*Programmer.*Bob.*' {} \; xargs sed -i -r '1,10 s/([ \t#*]*)(.*Programmer.*Bob.*)/\1LINE REPLACED/I' 

\ 1 conserve le motif correspondant à [\ t # *] *. On pourrait changer cela^[\ t # *] * qui pourrait ancrer le modèle au début de la ligne, mais (je crois) cette version actuelle changerait

** Text I don't want to remove ** Programmer Bob 

dans

** Text I don't want to remove ** LINE REPLACED 

Ce qui pourrait être meilleur. (J'ai également ajouté l'indicateur -I (capital i) à la commande find, qui ignore les fichiers binaires.)

Répondre

0

Vous mélangez des adresses et des commandes. substitution simple devrait fonctionner:

find . -exec grep -il -E 'Programmer.*Bob' {} \; \ 
    | xargs sed -i '1,10 s/.*Programmer.*Bob.*/LINE REPLACED/' 
+0

Je devais être avoir une vision terrible tunnel, parce que cette réponse semble logique parfaite, mais pour une raison que je viens Couldn » t le comprendre. Peut-être que je dois faire une pause. :) Je vais essayer et marquer comme correct si cela fonctionne. Merci! –

0
find . -type f -name "*.cpp"|xargs perl -pi -e 'if(/Programmer/ && /Bob/ && $.>=1 && $.<10){$_="line to replace"}' 
0

commande sed:

>sed '1,10 {s/programmer\|bob/LINE REPLACED/i;s/programmer\|bob//ig}' file 
Questions connexes