Encuentra y reemplaza cadenas en vim en varias líneas

Respuestas:

255

El :&&comando repite la última sustitución con las mismas banderas. Puede suministrarle los rangos adicionales (y concatenar tantos como desee):

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

Sin embargo, si tiene muchos rangos , prefiero usar un bucle:

:for range in split('6,10 14,18')| exe range 's/<search_string>/<replace_string>/g' | endfor
Ingo Karkat
fuente
55
Gracias. Nota para futuros usuarios: :6,10s/<search_string>/<replace_string>/g | :14,18&& | :20,23&& | :28,31&&también funcionará, forloop lo hace más fácil de recordar y ejecutar.
mu 無
55
Me alegro de que te guste! El :en los comandos posteriores es opcional, por cierto, por lo que puede guardar más pulsaciones de teclas.
Ingo Karkat
2
:&&me ahorrará cientos de pulsaciones de teclas por semana. ¡Gracias!
pdoherty926
Funciona sin la 'g' al final en mi vim. Entonces, cuando especifique el rango de línea, no necesita una bandera global
Tayyar R
3
@TayyarR El rango cubre las líneas (verticalmente, por así decirlo), mientras que la bandera 'g' determina si solo una o todas las coincidencias dentro de la línea (tan horizontalmente) se reemplazan.
Ingo Karkat
387

Reemplaza todo:

:%s/foo/bar/g

Encuentre cada aparición de 'foo' (en todas las líneas) y reemplácela con 'bar'.

Para líneas específicas:

:6,10s/foo/bar/g

Cambie cada 'foo' a 'bar' para todas las líneas desde la línea 6 a la línea 10 inclusive.

Jayanth Ramachandran
fuente
44
¿Cuál es el propósito de / g aquí? Lo siento, soy nuevo en Linux
Raja Anbazhagan
44
@RajaAnbazhagan La parte final de esta expresión, después de la última /, es donde se indican las banderas para la operación. Este comando normalmente reemplazará la primera coincidencia en una línea; Con la gbandera reemplazará todas las ocurrencias.
Litty
17
Realmente debe hacer referencia a sus fuentes (es decir, vim.wikia.com/wiki/Search_and_replace), si va a copiar y pasar el trabajo de otra persona.
Andrew S
2
¡La %cosa hace el trabajo! De lo contrario, es solo la primera vez.
Santosh Kumar
8
%=> ejecuta este comando en todas las líneas. g=> coincide con múltiples ocurrencias en la misma línea.
Shaahiin
55

Como nota al margen, en lugar de tener que escribir los números de línea, solo resalte las líneas donde desea buscar / reemplazar en uno de los modos visuales:

  • VISUALmodo ( V)
  • VISUAL BLOCKmodo ( Ctrl+ V)
  • VISUAL LINEmodo ( Shift+ V, funciona mejor en su caso)

Una vez que haya seleccionado las líneas para reemplazar, escriba su comando:

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

Notarás que el rango '<,'>se insertará automáticamente para ti:

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

Aquí '<simplemente significa la primera línea resaltada y '>significa la última línea resaltada .

Tenga en cuenta que el comportamiento puede ser inesperado cuando está en NORMALmodo: '<y '>señale el inicio y el final del último resaltado realizado en uno de los VISUALmodos. En cambio, en NORMALmodo, .se puede usar el número de línea especial , que simplemente significa la línea actual . Por lo tanto, puede encontrar / reemplazar solo en la línea actual como esta:

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

Otra cosa a tener en cuenta es que insertar un segundo :entre el rango y el comando buscar / reemplazar no hace daño, en otras palabras, estos comandos seguirán funcionando:

:'<,'>:s/<search_string>/<replace_string>/g
:.:s/<search_string>/<replace_string>/g
Atila O.
fuente
1
> Ejemplo: reemplazar texto de las líneas 6-10, 14-18 pero no de 11-13. - ¿Tu respuesta no responde esta misma pregunta, verdad?
poige
27

Puedes hacerlo con dos secuencias de buscar / reemplazar

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

La segunda vez, todo lo que necesita ajustar es el rango, por lo que en lugar de escribirlo todo, recordaría el último comando y editaría solo el rango

Lieven Keersmaekers
fuente
21

En vim, si está confundido sobre qué líneas se verán afectadas, use a continuación

 :%s/foo/bar/gc  

Cambie cada 'foo' a 'bar', pero solicite confirmación primero. Presione 'y' para sí y 'n' para no. No olvides guardar después de eso

:wq
SMJ
fuente
2
De hecho, puede usar la cbandera además de especificar el rango, por lo que :6,10s/<search_string>/<replace_string>/cfunciona. crepresenta confirm. Utilizo la cbandera con bastante frecuencia para evitar reemplazar accidentalmente palabras donde no pensaba que también existen allí.
Wolfson
16

VI buscar y reemplazar ejemplos de comandos

Digamos que le gustaría encontrar una palabra llamada "foo" y reemplazarla con "bar".

[Esc]Tecla de primer golpe

Escriba: (dos puntos) seguido de %s/foo/bar/y presione la tecla [Enter]

:%s/foo/bar/

arnav
fuente
11
Su :%s/<search_string>/<replace_string>/gcomando reemplazará todas las ocurrencias en todo el archivo. No es exactamente la respuesta a la pregunta, pero útil, sin embargo :)
Tanius
@tanius En realidad, fue la respuesta más directa a mi problema. Puede considerar modificar la pregunta para "Buscar y reemplazar cadenas en vim en las líneas" Seleccionadas "
Omid N
9

No necesitamos molestarnos en ingresar el número de línea actual.

Si desea cambiar cada uno fooa barla línea actual ( .) y las dos líneas siguientes ( +2), sólo tiene que hacer:

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

Si desea confirmar antes de realizar cambios, reemplace gcon gc:

:.,+2s/foo/bar/gc
lingjiankong
fuente
Otra cosa agradable que uso a menudo es :.,$s/foo/bar/gcbuscar y reemplazar desde la línea actual hasta el final del archivo.
Wolfson
3

Buscar y reemplazar

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

g => búsqueda global

c => Pedir confirmación primero

i => mayúsculas y minúsculas

Si desea un reemplazo directo sin confirmación, use el siguiente comando

:%s/search/replace/g

Si desea confirmación para cada reemplazo, ejecute el siguiente comando

:%s/search/replace/gc

Solicite confirmación primero, aquí la búsqueda no distingue entre mayúsculas y minúsculas.

:%s/search/replace/gci
Rahul Ravi
fuente
1

Está bien especificar el rango a través de la selección visual, pero cuando hay operaciones muy simples en un par de líneas que un operador puede seleccionar, lo mejor sería aplicar estos comandos como operadores.

Lamentablemente, esto no se puede hacer a través de los comandos vim estándar. Podrías hacer una especie de solución usando el! (filtro) operador y cualquier objeto de texto. Por ejemplo, para aplicar la operación a un párrafo, puede hacer:

!ip

Esto debe leerse como "¡Aplicar el operador! Dentro de un párrafo". El operador de filtro inicia el modo de comando e inserta automáticamente el rango de líneas seguido de un literal "!" que puedes eliminar justo después. Si aplica esto, al siguiente párrafo:

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

El resultado después de presionar "! Ap" sería como:

:.,.+5

Como el '.' (punto) significa la línea actual, el rango entre la línea actual y las 5 líneas posteriores se utilizarán para la operación. Ahora puede agregar el comando sustituto de la misma manera que antes.

Lo malo es que esto no es más fácil que seleccionar el texto para luego aplicar el operador. Lo bueno es que esto puede repetir la inserción del rango para otros rangos de texto similares (en este caso, párrafos) con un tamaño visiblemente diferente. Es decir, si luego desea seleccionar el rango más grande, el párrafo '.' Voluntad a la derecha.

Además, si le gusta la idea de usar objetos de texto semántico para seleccionar el rango de operación, puede verificar mi complemento EXtend.vim que puede hacer lo mismo pero de una manera más fácil.

Saul Axel Martinez Ortiz
fuente
0

Para responder esta pregunta:

:40,50s/foo/bar/g

reemplace foo con barra en estas líneas entre la línea 40 y la línea 50 (inclusive), cuando ejecute este comando, puede hacerlo en cualquier línea.

:50,40s/foo/bar/g

también funciona, vim le pedirá confirmación y luego hará el reemplazo por usted como si hubiera ingresado el primer comando.

:,50s/foo/bar/g

reemplace foo con barra en estas líneas entre la línea en la que se encuentra actualmente y la línea 50 (inclusive). (si está en una línea DESPUÉS de la línea 50, vim le pedirá confirmación nuevamente)

Para aclarar la diferencia entre vim y el complemento vrapper de Eclipse:

Tenga en cuenta que en varpper

:,50s/foo/bar/g El comando NO funcionará.

:50,40s/foo/bar/g funcionará sin pedir confirmación.

(Para la versión Vrapper 0.74.0 o anterior).

ZhaoGang
fuente
-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

Suponga que si desea reemplazar lo anterior con alguna otra información.

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

En esto, lo anterior se reemplazará con ( sys.pkg.mpu.umc.kdk.).

Sai Ganesh
fuente
No estoy seguro de que esto realmente responda la pregunta. De la pregunta parece que la persona que pregunta ya sabe cómo usar %spara modificar la entrada, pero quiere saber cómo hacerlo "semi-globalmente" (es decir, su especificación son las líneas 6-10 y 14-18 pero no en las líneas 11- 13)
Brandon Buck
1
Además, ¿qué es "COMANDO"? Y sufres del síndrome del palillo inclinado .
Martin Tournoij
Para curar que el síndrome, puede utilizar otro carácter como delimitador en lugar del predeterminado /, por ejemplo !, @, _::%s_/sys/sim/source/gm/kg/jl/ls/owow/lsal_sys.pkg.mpu.umc.kdk_g
MortezaE