Cerca e sostituisci in vim in righe specifiche


95

posso usare

:5,12s/foo/bar/g

per cercarlo fooe sostituirlo con bartra le righe 5 e 12. Come posso farlo solo nelle righe 5 e 12 (e non nelle righe intermedie)?

Risposte:


76

Vim ha atomi di espressioni regolari speciali che corrispondono in determinate righe, colonne, ecc .; puoi usarli (possibilmente in aggiunta al range) per limitare gli abbinamenti:

:5,12s/\(\%5l\|\%12l\)foo/bar/g

Vedere :help /\%l


8
Un modo più complicato di quanto mi aspettassi, ma risponde perfettamente alla mia domanda. Grazie!
pfnuesel

56

Puoi eseguire la sostituzione sulla riga 5 e ripeterla con il minimo sforzo sulla riga 12:

:5s/foo/bar
:12&

Come sottolineato da Ingo, :&dimentica le tue bandiere. Dato che stai usando /g, il comando corretto sarebbe :&&:

:5s/foo/bar/g
:12&&

Vedi :help :&e amici.


10
+1 per aver messo l'oscuro :&da usare. Se ci sono flag ( s/../../g), bisogna usare :&&, però ...
Ingo Karkat

10
@ IngoKarkat, per essere onesti, penso che \(\%5l\|\%12l\)sia più oscuro di:&
doubleDown

13

Puoi sempre aggiungere un calla fine. Questo chiederà conferma per ogni partita.

:5,12s/foo/bar/gc

1
Questo può essere un incubo se ci sono molte partite tra le linee 5 e 12 (tieni presente che c'è una gbandiera in gioco)
doppio Giù

1
@doubleDown Questa non vuole essere una soluzione universale (dove ci sono molti possibili candidati), ma nella maggior parte dei casi pensi davvero che premere n5 o 6 volte sia più oneroso che aggiungere \(\%5l\|\%12l\)all'istruzione sostitutiva?
Preside

Lo trovo utile, volevo cambiare ogni altra riga, questo sarebbe stato più veloce di quello che ho finito per fare.
tiktak

9

Domanda interessante. Sembra che ci sia solo la selezione dell'intervallo e nessuna selezione di più righe:

http://vim.wikia.com/wiki/Ranges

Tuttavia, se hai qualcosa di speciale sulle righe 5 e 12, potresti usare l' :goperatore. Se il tuo file ha questo aspetto (numeri solo per riferimento):

 1     line one
 2     line one
 3     line one
 4     line one
 5     enil one
 6     line one
 7     line one
 8     line one
 9     line one
10     line one
11     line one
12     enil one

E vuoi sostituire onecon enosulle righe dove c'è enilinvece di line:

:g/enil/s/one/eno/

5
questo in realtà sta assumendo molto
doubleDown

1

Potresti usare ed- un editor di testo orientato alla riga con comandi simili a vi e vim. Probabilmente è precedente a vi e vim.

In uno script (utilizzando un here document che elabora l'input fino al marker EndCommand) sarebbe simile a:

ed file <<EndCommands
    5
    s/foo/bar/g
    7
    s/foo/bar/g
    wq
EndCommands

Ovviamente, i comandi ed possono essere usati anche dalla riga di comando.


3
Non vedo un vantaggio vimsull'alternativa.
Bernhard

1
E lo stesso si può fare anche con Vim; i numeri possono effettivamente essere posti prima del :s, ma c'è ancora la duplicazione del :scomando (che la soluzione di romainl evita).
Ingo Karkat

La mia opinione era che l'utente volesse selezionare più di due righe per la modifica. In quel caso, un approccio non interattivo avrebbe potuto essere di interesse - cosa che AFAIK non può essere eseguita con vim.
suspectus

1
Oh, Vim può farlo (es. In modalità "Ex"), ma hai ragione che un altro strumento dovrebbe essere preferito a un editor interattivo. La mia preferenza sarebbe sed, però ...
Ingo Karkat
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.