texto substituir reemplazar por pegar linea dentro copiar con busqueda buscar vim replace

substituir - Buscar y reemplazar en Vim en todos los archivos del proyecto



vi editor buscar texto (9)

Estoy buscando la mejor manera de buscar y reemplazar (con confirmación) en todos los archivos de proyecto en Vim. Por "archivos de proyecto" me refiero a los archivos en el directorio actual, algunos de los cuales no tienen que estar abiertos.

Una forma de hacer esto podría ser simplemente abrir todos los archivos en el directorio actual:

:args ./**

y luego hacer la búsqueda y reemplazar en todos los archivos abiertos:

:argdo %s/Search/Replace/gce

Sin embargo, cuando hago esto, el uso de memoria de Vim salta de un par de docenas de MB a más de 2 GB, lo que no funciona para mí.

También tengo el complemento EasyGrep instalado, pero casi nunca funciona: o no encuentra todas las ocurrencias, o simplemente se cuelga hasta que presiono Ctrl C. Hasta ahora, mi forma preferida de realizar esta tarea es utilizar el término de búsqueda, usando su ventana quickfix abrir cualquier archivo que contenga el término y no haya sido abierto antes, y finalmente :bufdo %s/Search/Replace/gce .

Estoy buscando un complemento bueno y funcional que pueda usarse para esto o, alternativamente, un comando / secuencia de comandos que sería más fácil que el que estoy usando ahora.


Poblar :args desde un comando de shell

Es posible (en algunos sistemas operativos 1 )) suministrar los archivos para :args través de un comando de shell.

Por ejemplo, si tienes ack 2 instalado,

:args `ack -l pattern`

le pedirá a ack que devuelva una lista de archivos que contengan ''patrón'' y los pondrá en la lista de argumentos.

O con gre simple, supongo que sería:

:args `grep -lr pattern .`


A continuación, puede utilizar :argdo como se describe en el OP:

:argdo %s/pattern/replacement/gce


Poblar :args argumentos de la lista de arreglos rápidos

Consulte también la respuesta de nelstrom a una pregunta relacionada que describe un comando simple definido por el usuario que rellena el arglist de la lista de quickfix actual. Esto funciona muy bien con muchos comandos y complementos cuyo resultado termina en la lista de soluciones rápidas ( :vimgrep :Ack 3 :Ggrep 4 ).

La secuencia para realizar una búsqueda de todo el proyecto podría hacerse con:

:vimgrep /pattern/ **/* :Qargs :argdo %s/findme/replacement/gc

donde :Qargs es la llamada al comando definido por el usuario que rellena el arglist de la lista de arreglos rápidos.

También encontrará enlaces en la discusión posterior sobre complementos simples que reducen este flujo de trabajo a 2 o 3 comandos.

Campo de golf

  1. : h {arglist} - vimdoc.sourceforge.net/htmldoc/editing.html#{arglist}
  2. ack - ack
  3. ack.vim - github.com/mileszs/ack.vim
  4. fugitivo - github.com/tpope/vim-fugitive

Básicamente, quería el reemplazo en un solo comando y más importante dentro de vim

Basado en la respuesta de @Jefromi, he creado un atajo de teclado, que había establecido en mi archivo .vimrc como este

nmap <leader>r :!grep -r -l * /| xargs sed -i -e ''s///g''

ahora desde el vim, con un golpe de líder + r obtengo el comando cargado en vim, que edito como a continuación,

:!grep -r -l <find> <file pattern> | xargs sed -i -e ''s/<find>/<replace>/g''

Por lo tanto, hago el reemplazo con un solo comando y más importante dentro de vim


Decidí usar ack y Perl para resolver este problema con el fin de aprovechar las expresiones regulares de Perl más potentes en lugar del subconjunto de GNU.

ack -l ''pattern'' | xargs perl -pi -E ''s/pattern/replacement/g''

Explicación

ack

ack es una increíble herramienta de línea de comandos que es una mezcla de grep , find y expresiones regulares completas de Perl (no solo el subconjunto GNU). Está escrito en Perl puro, es rápido, tiene resaltado de sintaxis, funciona en Windows y es más amigable para los programadores que las herramientas de línea de comando tradicionales. Instálalo en Ubuntu con sudo apt-get install ack-grep .

xargs

Xargs es una antigua herramienta de línea de comandos de Unix. Lee los elementos de la entrada estándar y ejecuta el comando especificado seguido de los elementos leídos para la entrada estándar. Entonces, básicamente, la lista de archivos generados por ack se agrega al final del comando perl -pi -E ''s/pattern/replacemnt/g'' .

perl -pi

Perl es un lenguaje de programación. La opción -p hace que Perl cree un bucle alrededor de su programa que itera sobre los argumentos del nombre de archivo. La opción -i hace que Perl edite el archivo en su lugar. Puede modificar esto para crear copias de seguridad. La opción -E hace que Perl ejecute una línea de código especificada como el programa. En nuestro caso, el programa es solo una sustitución de expresiones regulares de Perl. Para obtener más información sobre las opciones de línea de comandos de Perl perldoc perlrun . Para obtener más información sobre Perl, consulte http://www.perl.org/ .


Gracias al comando cdo recientemente agregado, ahora puedes hacer esto en dos comandos simples usando la herramienta grep que hayas instalado. ¡No se requieren complementos adicionales !:

1. :grep <search term> 2. :cdo %s/<search term>/<replace term>/gc 3. (If you want to save the changes in all files) :cdo update

( cdo ejecuta el comando dado para cada término en la lista de soluciones rápidas, que rellena el comando grep ).

(Elimine la c al final del segundo comando si desea reemplazar cada término de búsqueda sin confirmar cada vez)


La otra gran opción aquí es simplemente no usar vim:

sed -i ''s/pattern/replacement/'' <files>

o si tiene alguna forma de generar una lista de archivos, tal vez algo como esto:

find . -name *.cpp | xargs sed -i ''s/pattern/replacement/'' grep -rl ''pattern1'' | xargs sed -i ''s/pattern2/replacement/''

¡y así!


Si no le importa introducir una dependencia externa, he ctrlsf.vim un plugin ctrlsf.vim (depende de ack o ag ) para hacer el trabajo.

Puede formatear y mostrar el resultado de búsqueda de ack / ag y sincronizar los cambios en el búfer de resultados con los archivos reales en el disco.

Tal vez la siguiente demostración explica más



tal vez haga esto:

:noautocmd vim /Search/ **/* :set hidden :cfirst qa :%s//Replace/gce :cnf q 1000@a :wa

Explicación:

  • :noautocmd vim /Search/ **/* ⇒ búsqueda ( vim es una abreviatura de vimgrep ) patrón en todos los archivos en todos los subdirectorios de la cwd sin activar autocmds ( :noautocmd ), por el bien de la velocidad.
  • :set hidden ⇒ permitir tener búferes modificados no se muestran en una ventana (podría estar en su vimrc)
  • :cfirst ⇒ saltar al primer resultado de búsqueda
  • qa ⇒ empezar a grabar una macro en registrar una
  • :%s//Replace/gce ⇒ reemplazar todas las apariciones del último patrón de búsqueda (todavía /Search/ en ese momento) con Replace :
    • varias veces en la misma línea ( g bandera)
    • con la confirmación del usuario (bandera c )
    • sin error si no se encuentra un patrón (bandera e )
  • :cnf ⇒ saltar al siguiente archivo en la lista creada por el comando vim
  • q ⇒ dejar de grabar macro
  • 1000@a ⇒ reproducir macro almacenada en el registro a 1000 veces
  • :wa ⇒ guardar todos los búferes modificados

* EDITAR * Vim 8 vías:

Comenzando con Vim 8 hay una mejor manera de hacerlo, ya que :cfdo itera en todos los archivos en la lista de soluciones rápidas:

:noautocmd vim /Search/ **/* :set hidden :cfdo %s//Replace/gce :wa