web-dev-qa-db-fra.com

Comment remplacer plusieurs lignes par un seul mot dans un fichier (remplacer)?

Le contenu de mon fichier filename est le suivant (par exemple):

My block of line starts from here 
START
First line
second line
third line
END
and end to here for example.

Je souhaite remplacer un bloc de lignes entre START et END par un seul mot, par exemple avec SINGLEWORD. Comme ci-dessous:

My block of line starts from here 
SINGLEWORD
and end to here for example.

Je peux trouver mon bloc de lignes en utilisant cette commande:

grep -Pzo "START(.|\n)*END" filename

Et le résultat de l'exécution de la commande ci-dessus sera comme ceci:

START
First line
second line
third line
END

Ensuite, j'ai utilisé cette commande pour combiner toutes les lignes en une seule ligne:

LAST_RESULT | sed -e :a -e '/$/N; s/\n/ /; ta'

Ensuite, je vais obtenir ce résultat:

START First line second line third line END

Et avec ma dernière commande, LAST_RESULTS | sed 's/.*/SINGLEWORD/', je les change en "SINGLEWORD" et j’obtiens ce résultat.

SINGLEWORD

Maintenant, ce que je veux, c'est: Comment puis-je utiliser cette commande (ou votre commande de suggestion) et remplacer (à la place) mon bloc de lignes en mot "SINGLEWORD"? Et le résultat final sera comme ce fichier:

My block of line starts from here 
SINGLEWORD
and end to here for example.
8
αғsнιη

Cela peut être fait très facilement dans Perl:

$ Perl -i -p0e 's/START.*?END/SINGLEWORD/s' file
$ cat file
My block of line starts from here 
SINGLEWORD
and end to here for example. 

Explication

-0 définit le séparateur de ligne sur null

-p applique le script donné par -e à chaque ligne et affiche cette ligne

Le modificateur d'expression régulière:

  • /s Traite la chaîne comme une seule ligne. Autrement dit, changez . pour qu’il corresponde à n’importe quel caractère, même à une nouvelle ligne, auquel il ne correspond normalement pas.

Pourquoi le ?:

  • Par défaut, un sous-motif quantifié est "glouton", c'est-à-dire qu'il correspondra autant de fois que possible (en fonction d'un emplacement de départ particulier) tout en permettant au reste du motif de correspondre. Si vous voulez qu'il corresponde au nombre minimum de fois possible, suivez le quantificateur avec un ?.
12
Sylvain Pineau

Je me demandais si cela était possible sans Perl, python et d’autres. Et j'ai trouvé cette solution en utilisant sed:

$ sed ':a;N;$!ba;s/START.*END/SINGLEWORD/g' filename

Explication:

  1. : a crée une étiquette 'a'
  2. N ajoute la ligne suivante à l'espace du motif
  3. $! si ce n'est la dernière ligne , ba branche (aller à) étiquette 'a'
  4. s substitue , /START.*END/ par SINGLEWORD, /g correspondance globale (autant de fois que possible)

Il a été trouvé ici .

@ KasiyA, merci, j'ai appris beaucoup de choses intéressantes!

13
c0rp