Trova e sostituisci le stringhe in vim su più righe


354

Posso fare :%s/<search_string>/<replace_string>/gper sostituire una stringa in un file o :s/<search_string>/<replace_string>/per sostituire nella riga corrente.

Come posso selezionare e sostituire le parole da righe selettive in vim?

Esempio: sostituire il testo dalle righe 6-10, 14-18ma non da 11-13.



Risposte:


255

Il :&&comando ripete l'ultima sostituzione con gli stessi flag. Puoi fornire gli intervalli aggiuntivi (e concatenare quanti ne desideri):

:6,10s/<search_string>/<replace_string>/g | 14,18&&

Se hai molti intervalli , preferirei usare un loop:

:for range in split('6,10 14,18')| exe range 's/<search_string>/<replace_string>/g' | endfor

5
Grazie. Nota per i futuri utenti: :6,10s/<search_string>/<replace_string>/g | :14,18&& | :20,23&& | :28,31&&funzionerà anche, il forciclo rende più facile da ricordare ed eseguire.
mu 無

5
Contento che ti piaccia! Il :sui comandi successivi è facoltativo, tra l'altro, in modo da poter salvare qualche altra sequenza di tasti.
Ingo Karkat,

2
:&&mi farà risparmiare centinaia di sequenze di tasti a settimana. Grazie!
pdoherty926,

Funziona senza la 'g' alla fine nella mia vim. Quindi forse quando specifichi l'intervallo di linee non è necessario il flag globale
Tayyar R

3
@TayyarR L'intervallo copre le linee (in verticale, per così dire), mentre il flag 'g' determina se solo una o tutte le corrispondenze all'interno della linea (quindi in orizzontale) vengono sostituite.
Ingo Karkat,

387

Sostituisci tutto:

:%s/foo/bar/g

Trova ogni occorrenza di "pippo" (in tutte le righe) e sostituiscilo con "barra".

Per linee specifiche:

:6,10s/foo/bar/g

Cambia ogni "pippo" in "barra" per tutte le linee dalla linea 6 alla linea 10 inclusa.


4
qual è lo scopo di / g qui? Scusa, sono nuovo di Linux
Raja Anbazhagan,

4
@RajaAnbazhagan La parte finale di questa espressione, dopo l'ultima /, è dove si indicano i flag per l'operazione. Questo comando sostituirà normalmente la prima corrispondenza su una riga; Con la gbandiera sostituirà tutte le occorrenze.
Litty,

17
Dovresti davvero fare riferimento alle tue fonti (es. Vim.wikia.com/wiki/Search_and_replace), se hai intenzione di copiare e incollare il lavoro di un'altra persona.
Andrew S,

2
La %cosa fa il lavoro! Altrimenti, è solo la prima occorrenza.
Santosh Kumar,

8
%=> esegui questo comando su tutte le righe. g=> trova più ricorrenze nella stessa riga.
Shaahiin,

55

Come nota a margine, invece di dover digitare i numeri di riga, evidenzia solo le linee in cui vuoi trovare / sostituire in una delle modalità visive:

  • VISUALmode ( V)
  • VISUAL BLOCKmodalità ( Ctrl+ V)
  • VISUAL LINEmode ( Shift+ V, funziona meglio nel tuo caso)

Dopo aver selezionato le righe da sostituire, digitare il comando:

:s/<search_string>/<replace_string>/g

Noterai che l'intervallo '<,'>verrà inserito automaticamente per te:

:'<,'>s/<search_string>/<replace_string>/g

Qui '<significa semplicemente prima evidenziato linea , e '>mezzi ultima linea evidenziata .

Si noti che il comportamento potrebbe essere inaspettato quando in NORMALmodalità: '<e '>indicare l'inizio e la fine dell'ultimo momento saliente fatto in una delle VISUALmodalità. Invece, in NORMALmodalità, è .possibile utilizzare il numero di riga speciale , che significa semplicemente riga corrente . Quindi, puoi trovare / sostituire solo sulla riga corrente in questo modo:

:.s/<search_string>/<replace_string>/g

Un'altra cosa da notare è che l'inserimento di un secondo :tra l'intervallo e il comando trova / sostituisci non danneggia, in altre parole, questi comandi continueranno a funzionare:

:'<,'>:s/<search_string>/<replace_string>/g
:.:s/<search_string>/<replace_string>/g

1
> Esempio: sostituire il testo dalle righe 6-10, 14-18 ma non dall'11 al 13. - la tua risposta non risponde a questa domanda, vero?
poige

27

Puoi farlo con due sequenze trova / sostituisci

  :6,10s/<search_string>/<replace_string>/g
  :14,18s/<search_string>/<replace_string>/g

La seconda volta, tutto ciò che serve per regolare è l'intervallo, quindi invece di digitare tutto, richiamerei l'ultimo comando e modificherei solo l'intervallo


21

Se sei confuso su quali linee saranno interessate, usa sotto

 :%s/foo/bar/gc  

Cambia ogni "foo" in "bar", ma prima chiedi conferma. Premere 'y' per sì e 'n' per no. Non dimenticare di salvare dopo

:wq

2
Puoi effettivamente usare il cflag oltre a specificare l'intervallo, quindi :6,10s/<search_string>/<replace_string>/cfunziona. csta per confirm. Uso cabbastanza spesso la bandiera per impedire di sostituire accidentalmente le parole in cui non pensavo che esistessero anche lì.
Wolfson,

16

VI cerca e sostituisce esempi di comandi

Diciamo che vorresti trovare una parola chiamata "foo" e sostituirla con "bar".

[Esc]Tasto primo colpo

Digitare: (due punti) seguito da %s/foo/bar/e premere il tasto [Invio]

:%s/foo/bar/


11
Il tuo :%s/<search_string>/<replace_string>/gcomando sostituirà tutte le occorrenze nell'intero file. Non esattamente la risposta alla domanda, ma utile comunque :)
tanius

@tanius In realtà è stata la risposta più diretta al mio problema. Puoi considerare di modificare la domanda in "Trova e sostituisci le stringhe in vim sulle linee" Selezionate "
Omid N

9

Non dobbiamo preoccuparci di inserire il numero di riga corrente.

Se desideri cambiarne ognuna foocon la barriga corrente ( .) e le due righe successive ( +2), fai semplicemente:

:.,+2s/foo/bar/g

Se si desidera confermare prima di apportare modifiche, sostituire gcon gc:

:.,+2s/foo/bar/gc

Un'altra cosa carina che uso spesso è :.,$s/foo/bar/gccercare e sostituire a partire dalla riga corrente fino alla fine del file.
Wolfson,

3

Cerca e sostituisci

:%s/search\|search2\|search3/replace/gci

g => ricerca globale

c => Chiedi prima la conferma

i => Maiuscole / minuscole

Se si desidera la sostituzione diretta senza conferma, utilizzare il comando seguente

:%s/search/replace/g

Se si desidera la conferma per ogni sostituzione, eseguire il comando seguente

:%s/search/replace/gc

Chiedi prima la conferma, qui la ricerca non farà distinzione tra maiuscole e minuscole.

:%s/search/replace/gci

1

Specificare l'intervallo attraverso la selezione visiva è ok ma quando ci sono operazioni molto semplici su solo un paio di linee che possono essere selezionate da un operatore, sarebbe meglio applicare questi comandi come operatori.

Questo purtroppo non può essere fatto attraverso i comandi vim standard. È possibile eseguire una sorta di soluzione utilizzando il! (filtro) operatore e qualsiasi oggetto di testo. Ad esempio, per applicare l'operazione a un paragrafo, è possibile eseguire:

!ip

Questo deve essere letto come "Applica l'operatore! All'interno di un paragrafo". L'operatore di filtro avvia la modalità di comando e inserisce automaticamente l'intervallo di righe seguito da un "!" Letterale che puoi eliminare subito dopo. Se lo applichi, al seguente paragrafo:

1
2  Repellendus qui velit vel ullam!
3  ipsam sint modi! velit ipsam sint
4  modi! Debitis dolorum distinctio
5  mollitia vel ullam! Repellendus qui
6  Debitis dolorum distinctio mollitia
7  vel ullam! ipsam
8
9  More text around here

Il risultato dopo aver premuto "! Ap" sarebbe come:

:.,.+5

Come il '.' (punto) indica la linea corrente, l'intervallo tra la linea corrente e le 5 linee successive verranno utilizzati per l'operazione. Ora puoi aggiungere il comando sostitutivo allo stesso modo di prima.

La parte negativa è che non è più facile selezionare il testo per quest'ultimo applicando l'operatore. La parte buona è che questo può ripetere l'inserimento dell'intervallo per altri intervalli di testo simili (in questo caso, paragrafi) con dimensioni visivamente diverse. Cioè, se in seguito si desidera selezionare l'intervallo più grande, il paragrafo "." volontà a destra.

Inoltre, se ti piace l'idea di utilizzare oggetti di testo semantici per selezionare l'intervallo di operazioni, puoi controllare il mio plugin EXtend.vim che può fare lo stesso ma in modo più semplice.


0

Per rispondere a questa domanda:

:40,50s/foo/bar/g

sostituisci foo con la barra in queste righe tra la 40a e la 50a (compresa), quando esegui questo comando puoi attualmente in qualsiasi riga.

:50,40s/foo/bar/g

funziona anche, vim ti chiederà comfirm e quindi eseguirà la sostituzione per te come se tu avessi inserito il primo comando.

:,50s/foo/bar/g

sostituisci foo con la barra in queste righe tra la linea in cui ti trovi attualmente e la 50a linea (incluso). (se sei in linea DOPO la vim della 50a riga chiederai di nuovo la conferma)

Per chiarire la differenza tra vim e il plugin vrapper di Eclipse:

Si noti che in varpper

:,50s/foo/bar/g il comando NON funzionerà.

:50,40s/foo/bar/g funzionerà senza chiedere conferma.

(Per Vrapper versione 0.74.0 o precedente).


-5
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal

Supponiamo che si desideri sostituire quanto sopra con alcune altre informazioni.

COMMAND(:%s/\/sys\/sim\/source\/gm\/kg\/jl\/ls\/owow\/lsal/sys.pkg.mpu.umc.kdk./g)

In questo quanto sopra verrà sostituito con ( sys.pkg.mpu.umc.kdk.).


Non sono sicuro che questo risponda effettivamente alla domanda. Dalla domanda sembra che la persona che sta chiedendo sia già a conoscenza di come utilizzare %sper modificare l'input ma vuole sapere come farlo "semi-globalmente" (cioè la sua specifica è le righe 6-10 e 14-18 ma non sulle righe 11- 13).
Brandon Buck,

1
Inoltre che cos'è "COMANDO"? E soffri di sindrome dello stecchino pendente .
Martin Tournoij,

Per curare che la sindrome, è possibile utilizzare un altro carattere come delimitatore posto di quella predefinita /, ad esempio !, @, _::%s_/sys/sim/source/gm/kg/jl/ls/owow/lsal_sys.pkg.mpu.umc.kdk_g
MortezaE
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.