Vim search sostituisce tutti i file nella cartella corrente (progetto)


37

Una delle domande aperte che ho su Vim è se esiste un modo per eseguire una ricerca / sostituzione nel progetto corrente (abbiate pazienza se uso questa nozione ereditata da altri editor).

Ad esempio, supponiamo che io voglia cercare i miei file di progetto per un nome di metodo e rinominare tutte le istanze di quella chiamata di metodo.

Ecco come posso procedere con Sublime.

inserisci qui la descrizione dell'immagine

Come lo faresti in Vim (possibilmente MacVim) senza fare affidamento su altri programmi come acko sed?

Risposte:


35

Esistono diversi modi per farlo.

All'interno della directory corrente

Se si desidera eseguire la ricerca / sostituzione in una struttura di progetto, è possibile utilizzare l' elenco degli argomenti di Vim .

Basta aprire Vim e quindi utilizzare il :argscomando per popolare l'elenco degli argomenti. Puoi passare più nomi di file o persino globs.

Ad esempio, :args **/*.rbcercherà ricorsivamente nella directory corrente i file ruby. Nota che è anche come aprire Vim con vim **/*.rb. Puoi anche usare il findcomando della shell per ottenere un elenco di tutti i file nella directory corrente eseguendo:

:args `find . -type f`

È possibile visualizzare l'elenco args corrente eseguendolo :argsda solo. Se si desidera aggiungere o eliminare file dall'elenco, è possibile utilizzare :argaddo:argdelete rispettivamente comandi o.

Una volta che sei soddisfatto dell'elenco, ora puoi usare Vim's potente :argdo comando di che esegue un comando per ogni file nell'elenco degli argomenti::argdo %s/search/replace/g

Ecco alcuni suggerimenti per la ricerca (basato su alcuni dei commenti):

  1. Utilizzare un limite di parole se si desidera cercare "foo" ma non "foo_bar". Utilizzare i costrutti \<e \>attorno al modello di ricerca in questo modo::argdo %s/\<search\>/foobar/g
  2. Usa un /cflag di ricerca se vuoi che Vim chieda conferma prima di sostituire un termine di ricerca.
  3. Utilizzare un /eflag di ricerca se si desidera saltare gli errori "modello non trovato".
  4. È inoltre possibile scegliere di salvare il file dopo aver eseguito la ricerca: :argdo %s/search/replace/g | update. Qui, :updateviene utilizzato perché salverà il file solo se è stato modificato.

Buffer aperti

Se hai già buffer aperti e vuoi fare la ricerca / sostituzione, puoi usare :bufdo, che esegue un comando per ogni file nell'elenco dei buffer (:ls ).

Il comando è molto simile a :argdo: :bufdo %s/search/replace/g

Simile a :argdoe :bufdo, esiste :windoe :tabdoagisce rispettivamente su finestre e schede. Sono meno usati ma ancora utili da sapere.


4
Probabilmente potrebbe essere una buona idea usare la /cbandiera per confermare le sostituzioni.
Romainl

3
Vorrei anche raccomandare di usare i limiti di parola \<e \>intorno al searchper evitare sostituzioni di parole parziali.
tommcdo,

1
Un altro commento è che la directory di lavoro di vim è di default dove hai avviato vim, non la directory del file corrente. È possibile impostare la directory di lavoro sul file corrente utilizzando :cd %:p:h. Altre opzioni di directory di lavoro sono elencate in vim.wikia.com/wiki/Set_working_directory_to_the_current_file .
Studgeek

30

Diciamo che abbiamo una struttura di progetto semplice come questa:

inserisci qui la descrizione dell'immagine

assomiglia a greeting.txt

inserisci qui la descrizione dell'immagine

e sembra info / age.txt

inserisci qui la descrizione dell'immagine

Diciamo che vogliamo sostituire tutte le occorrenze di Sam con Bob. Ecco cosa faremmo:

  1. Imposta directory di lavoro

    Assicurati che l'attuale directory di lavoro di Vim sia la radice del progetto (non ti mostrerà come farlo qui).

  2. Trova file che contengono "Sam"

    Usa il comando vimgrep di Vim per cercare tutte le occorrenze di Sam all'interno del progetto (nota: le **/*ricerche in tutti i file in modo ricorsivo)

    :vimgrep /Sam/gj **/*
    

    Questo popolerà l'elenco delle correzioni rapide con tutte le istanze di Sam. Se si desidera visualizzare l'elenco delle correzioni rapide, è possibile utilizzare il comando Vim:copen inserisci qui la descrizione dell'immagine

  3. Sostituisci tutti i file che contengono "Sam"

    Ora vogliamo eseguire il comando sostitutivo di Vim all'interno di ogni file nell'elenco di aggiornamenti rapidi. Possiamo farlo usando il :cfdo {cmd}comando che esegue {cmd} in ciascun file nell'elenco di correzioni rapide. Il {cmd} specifico che vogliamo usare è substituteo sin breve. La linea completa sarebbe simile a:

    :cfdo %s/Sam/Bob/g
    

    Puoi aggiungere il flag c per confermare tutte le sostituzioni se ti piace:

    :cfdo %s/Sam/Bob/gc
    
  4. Salva tutti i file

    :cfdo update
    

2
Mi piace di più. È semplice e funziona con Ack (o qualsiasi plug-in che popola la finestra di QuickFix).
Zuhaib,

1
Questa è una grande risposta
Peoplee

2
Stavo ricevendo "nessuna scrittura dall'ultima modifica", cfdo %s/Sam/Bob/g | update
risolvendo il problema

@hakunin Ti consiglio di impostare l' hiddenopzione :set hiddense non l'hai già fatto.
Niko Bellic,

3

Sebbene non sia una soluzione VIM, se si utilizza VI / VIM potrebbe essere più semplice utilizzare una soluzione CLI. Per modificare tutti i file nella directory corrente, utilizzare perlcome è stato fatto per situazioni come questa:

$ perl -pi -e 's/foo/bar/g' *

Se devi farlo anche nelle sottodirectory, di solito mi associo perla find:

$ find . -name '*' -print0 | xargs -0 perl -pi -e 's/foo/bar/g'

La cosa bella di questo è che puoi facilmente affinare ulteriormente l'elenco a tipi di file specifici. Ad esempio, per limitare ai file Python:

$ perl -pi -e 's/foo/bar/g' *.py
$ find . -name '*.py' -print0 | xargs -0 perl -pi -e 's/foo/bar/g'

1

Per sostituire la frase con un'altra, puoi usare la modalità Vim Ex.

Ad esempio ( exè alias di vim -E):

$ ex -s +'bufdo!%s/foo/bar/g' -cxa *.*

Ricorsivamente in bash / zsh (con globstarset, ad es. shopt -s globstar):

$ ex -s +'bufdo!%s/foo/bar/g' -cxa **/*.*
$ ex -s +'n **/*.*' +'bufdo!%s/foo/bar/g' -cxa

Ricorsivamente (utilizzando finde ignorando i file nascosti come i .gitfile):

$ find . -type f -not -path '*/\.*' -exec ex -s +'bufdo!%s/foo/bar/g' -cxa {} "+"

Nota: il :bufdocomando non è POSIX .

Nota: la sintassi -not -path '*/\.*'viene utilizzata per ignorare i file nascosti (come .git).



0

Ecco il comando shell usando finded exeditor (senza usare:bufdo ):

find . -name '*.rb' -exec ex +'%s/foo/bar/ge' -V1 -scwq! {} ';'

Ciò modificherà sul posto tutti i *.rbfile nella cartella corrente (ricorsivamente) e sostituirà foocon bar.

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.