web-dev-qa-db-fra.com

Remplacer la chaîne multiligne dans les fichiers

J'ai un certain nombre de fichiers que je veux mettre à jour en remplaçant une chaîne multiligne avec une autre chaîne multiligne. Quelque chose dans le sens de:

* Some text, 
* something else
* another thing

Et je veux le remplacer par:

* This is completely
* different text

Le résultat serait qu'après le remplacement, le fichier contenant le premier bloc de texte, contiendra maintenant la deuxième chaîne (le reste du fichier est inchangé).

Une partie du problème est que je dois trouver la liste des fichiers à mettre à jour dans le système de fichiers. Je suppose que je peux utiliser Grep pour cela (bien que ce n'est pas aussi facile à voir avec les chaînes multilignes), puis tuez-la dans SED peut-être?

Y a-t-il un moyen facile de faire ceci? =Sed est une option, mais c'est gênant parce que je dois ajouter\n, etc. est un moyen de dire "Prenez l'entrée de ce fichier, le correspondre à ces fichiers, puis remplacez-le avec le Contenu de cet autre fichier "? Je peux utiliser python Si besoin d'être, mais je veux quelque chose de rapide et simple, donc s'il y a une utilité disponible, je préférerais utiliser mon propre script (que je sais faire).

18
ventsyv

Substitut "certains ...\n ... chose" par le contenu du fichier "nouveau" dans un ou plusieurs fichiers d'entrée

Perl -i -p0e 's/Some.*?thing\n/`cat new`/se' input.txt ...
  1. -i Pour changer INPUT.TXT directement
  2. -p0 Fichier d'entrée SLURP et imprimer à la fin
  3. s/regexp/.../s Dans regexp . Est .|\n
  4. s/.../exp/e Remplacer par eval(exp)
  5. nouveau - Un fichier contenant le texte de remplacement (c'est complètement ... texte différent)
  6. si utile, vous pouvez développer le texte d'origine s/Some text\n...\n...thing\n/...
12
JJoao
sed -e :n -e '$!N;/\n.*\n/!{$!bn
};  s/some text,\n* *something else\n* *another thing/this is completely\
different text/;P;D' <infile

Je crains que vous n'ayez pas du temps difficile à trouver une solution qui vous convient jusqu'à ce que vous martiez une description concrète du problème - mais c'est ce que QA est le mieux adapté pour, comme je le vois. Peut-être que cela vous donnera une idée - il gardera toujours 3 lignes dans un espace de motif à la fois - avec une lunette 2 lignes - tout en faisant glisser vers l'avant à travers le fichier d'entrée, une ligne à la fois.

Il devrait être en mesure de faire correspondre votre chaîne si elle couvre plusieurs lignes ou pas - jusqu'à trois, c'est-à-dire. Mais il n'y a aucune disposition pour refléter cette provision dans le remplacement - elle couvre toujours deux lignes comme écrit.

5
mikeserv

Une autre approche sed.

sed '1s/* Some text, 
* something else
* another thing/* This is completely
* different text/' infile.txt 
1
αғsнιη

Pas trop fort (parce que ne tonnez pas la deuxième chaîne, mais il est facile de régler) et peut être le compilant de Posix mais très simple:

sed '/^Some text/{:1;/another thing$/!{N;b 1}
     s/.*/this is completely\ndifferent text/g}' input.txt

La première commande ajoutez des lignes de du texte jusqu'à ce que ce soit rempli une autre chose puis seconde ligne le change vers un autre texte.

[~ # ~] note [~ # ~]] La limitation est celle du texte doit toujours être suivie par une autre chose .

0
Costas