Come posso sostituire più righe con una singola parola nel file (sostituzione sul posto)?


9

Il contenuto del mio filenamefile è il seguente (ad esempio):

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

Voglio sostituire il blocco di linee tra STARTe ENDcon una sola parola, ad esempio con SINGLEWORD. Come sotto:

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

Posso trovare il mio blocco di linee usando questo comando:

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

E il risultato dell'esecuzione sopra il comando sarà così:

START
First line
second line
third line
END

Quindi ho usato questo comando per combinare tutte le linee in un'unica linea:

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

Quindi otterrò questo risultato:

START First line second line third line END

E con il mio ultimo comando LAST_RESULTS | sed 's/.*/SINGLEWORD/'li cambio in "SINGLEWORD"e ottengo questo risultato.

SINGLEWORD

Ora quello che voglio è: come posso usare questo comando (o il tuo suggerimento) e sostituire (sul posto) il mio blocco di linee con la parola "SINGLEWORD"? E il risultato finale sarà come questo file:

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

Risposte:


14

Questo può essere fatto molto facilmente in 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. 

Spiegazione

-0 imposta il separatore di riga su null

-papplica lo script fornito da -eciascuna riga e stampa quella riga

Il modificatore regexp:

  • /sTratta la stringa come una riga singola. Cioè, cambia .per abbinare qualsiasi personaggio, anche una nuova riga, che normalmente non corrisponderebbe.

Perché il ?:

  • Per impostazione predefinita, un modello secondario quantificato è "avido", ovvero corrisponderà il maggior numero di volte possibile (data una particolare posizione iniziale) pur consentendo al resto del modello di corrispondere. Se si desidera che corrisponda al numero minimo di volte possibile, seguire il quantificatore con a ?.

@KasiyA: l'uso seddovrebbe essere possibile ma probabilmente più difficile da leggere (guarda questa domanda )
Sylvain Pineau,

Un altro perché il mio INIZIO E FINE modello ha i caratteri speciali ( /, *, ?) in esso e questi sono solo esempio. e potresti spiegare il tuo comando.
αғsнιη,

@KasiyA si può sfuggire tali caratteri con \ (esattamente come con sed): \/, \*,\?
Sylvain Pineau

@KasiyA Ci ho provato perl -i -p0e 's/\/\*.*?\*\//SINGLEWORD/sm'. Dovrebbe funzionare
Sylvain Pineau il

@KasiyA Penso di aver finito con le spiegazioni ora;)
Sylvain Pineau,

14

Mi chiedevo se questo è possibile senza perl, pythone altri. E ho trovato questa soluzione usando sed:

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

Spiegazione:

  1. : a crea un'etichetta 'a'
  2. N aggiunge la riga successiva allo spazio del motivo
  3. $! se non l'ultima riga , ba branch (vai a) etichetta 'a'
  4. s sostituisce , /START.*END/con SINGLEWORD, / g corrispondenza globale (quante volte può)

E 'stato trovato qui .

@KasiyA, grazie ho imparato molte cose interessanti!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.