Linee duplicate che iniziano con "x", sostituendo "x" nel duplicato con "y"?


9

Ho un file con il seguente modello:

foo 111
baz
foo 222
baz
foo 333
baz

che deve essere trasformato in

foo 111
bar 111
baz
foo 222
bar 222
baz
foo 333
bar 333
baz

Quindi, duplica tutte le righe che iniziano con foo, e cambia solo foonel duplicato ma lascia intatto il resto della riga (che differisce in ciascun caso). Come fare questo?


Se non sei legato all'inferno su una regexp, una macro andrà bene. Non importa molto in casi semplici come questo, ma se hai qualcosa di un po 'più complicato è un'alternativa molto valida.
PhilippFrank,

Risposte:


19

Ecco qui:

:g/foo/t.|s//bar

decomposizione:

:g/foo/    " start a global command applied on all lines matching 'foo'
t.         " duplicate the current line (the cursor is now on the new line)
|          " chain a new command
s//bar     " substitute the last searched element with 'bar'

Perché il gcomando aggiorna il modello di ricerca, quindi puoi ometterlo per sostituirlo nel comando sostitutivo. (ref:, :h :gcerca search pattern).


Versione precedente:

:g/foo/norm! yyp:s/foo/bar^M

decomposizione:

:g            start a global command
/foo/         apply only on lines having 'foo'
norm!         execute a normal command
yyp           duplicate the line
:s//bar       replace foo with bar on the line (the duplicated one)
^M            add enter to execute the substitution

Per inserire la ^Mstampa Ctrl+ve enter.

Nota : originariamente ho trovato la versione "precedente", prima di conoscere il tcomando. Lo lascerò ma non consiglierò di usarlo. Il primo è più pulito e semplice.


Risolta, la "versione più semplice" ha funzionato perfettamente. La prima versione, tuttavia, ha portato alla riga duplicata che inizia ancora con foo....
LB7979,

strano, sei entrato ^Mcome ti ho spiegato?
nobe4,

Mio male, non ho letto bene. Anche la prima soluzione funziona!
LB7979,

Non so perché ti preoccupi di includere la versione complicata. La versione più semplice è ... più semplice. ;) (Per non parlare della conformità POSIX.) Perché non metterlo per primo?
Wildcard il

1
Inizialmente mi è venuta in mente la prima versione, che per me era più naturale, perché all'epoca non ne ero a conoscenza t, e poi ho aggiunto la seconda. Cambierò l'ordine, hai ragione. Che ne dici del primo POSIX?
nobe4,

1

Faccio cose del genere tutto il tempo e faccio semplicemente qualcosa del genere %s/^foo \(.*\)/foo \1\rbar \1/(in parte perché faccio anche molte attività simili che non possono essere trasformate in qualcosa di intelligente usando una funzione di copia, e ormai \(.*\)fa parte della mia memoria muscolare).

Sospetto che non sia conforme a POSIX (non funziona su altri cloni vi), ma l'utilizzo di ^M( C-VReturn) invece di \rsembra funzionare sulla maggior parte degli altri cloni vi.

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.