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.