Pregunta

¿Cómo puedo reemplazar los primeros diez caracteres de una línea donde esos diez caracteres coinciden con un patrón particular con los primeros diez caracteres de la línea de arriba?

Editar: no estaba claro si estaba pidiendo reemplazar los primeros diez caracteres donde la coincidencia podría aparecer en cualquier lugar dentro de la línea, así que tal vez tome nota en su respuesta si se trata de este caso (llame a este caso B y el caso previsto A?)

¿Fue útil?

Solución

Prehaps:

:%s/^\(.\{10}\)\(.*\n\)abcdefghij\(.*\)/\1\2\1\3/

Donde 'abcdefghij' es la cadena de 10 caracteres en la segunda línea

Otros consejos

Algo como esto funcionaría:

%s/^.\{10\}/\=strpart(get(getbufline("", line(".")-1), 0, ""), 0, 10)/

donde ^. \ {10 \} es su patrón real.

%s/                      # substitute all lines matching…
^.\{10\}                 # your pattern
/                        # …with…
\=                       # an expression:
strpart(                 # gets the part of a string
  get(                   # gets an element of a list
    getbufline(          # gets a list of lines from the current buffer
      "", line(".")-1)   # getbufline() the line before the current line
  , 0, "")               # get() first line in buffer, default to ""
, 0, 10)                 # strpart() first ten characters
/                        # …end of substitution
:2,$g/<pattern>/s/^.\{10}/\=strpart(getline(line(".")-1),0,10)
  • 2, $ es nuestro rango (ya que la primera línea no tiene línea anterior)
  • g // le permite ejecutar un comando en líneas que coinciden con un patrón determinado.
  • s / ^. \ {10} / reemplazará los primeros 10 caracteres de una línea
  • \ = le permite sustituir el resultado de una expresión vim en un :s//
  • line (". ") es el número de línea actual
  • getline (line (". ") - 1) es el texto de la línea anterior
  • strpart (getline (line (". ") - 1), 0,10) son los primeros 10 caracteres de la línea anterior

Por ejemplo 2, $ g / frog / s / ^. \ {10} / \ = strpart (getline (line (". ") - 1), 0,10) cambiará:

I like eating mangos
before frying frogs legs
I wish I had a puppy
She gave Dad a frog

A esto:

I like eating mangos
I like eating frogs legs
I wish I had a puppy
I wish I had a frog

Si tengo una acción compleja como esa, generalmente grabo una macro usando el comando q . Algo así (no probado):

/<pattern>
qq
10x
k
10yl
j
P
n
q

Y luego, repetidamente, emita esa macro como @q opcionalmente prefijada con un conteo.

Puede usar buscar y reemplazar:

:7,9 s/foo/bar/c

Este ejemplo busca de la línea 7 a la 9 para cada aparición de 'foo', y lo reemplaza con 'barra', solicitando una confirmación en cada golpe. Si no desea confirmar, suelte la c al final. Elija el rango como mejor le parezca y esto lo llevará a donde quiera

Usando solo los movimientos de vim y tirando / pegando .. Dado el contenido del archivo de ...

1234567890abcdef
qwertyuiopasdfgh

Con el cursor en q, 10x , el archivo se convierte en:

1234567890abcdef
asdfgh

Mueve el cursor a la primera línea (usando k lo hará), luego haz 10yl (tira 10 caracteres, a la derecha)

Luego retroceda una línea, j , y pegue P (mayúscula, para pegar debajo del cursor) y el archivo se convertirá en:

1234567890abcdef
1234567890asdfgh

En resumen, comenzando con el cursor en q:

10xk10yljP

..que puede pegar o asignar a una macro

Sería más corto si hubiera un atajo obvio para pegar sobrescribiendo, pero no pude encontrar tal cosa

Otra opción es una búsqueda / reemplazo de expresiones regulares de aspecto increíblemente oscuro.

Visual-line selecciona las dos líneas de destino y ejecuta la siguiente búsqueda y reemplazo:

:'<,'>s/\(\(.\{10\}\).*\)\n\(.\{10\}\)\(.*\)$/\1\r\2\4/

Básicamente agarra ..

  • \ 1 : toda la primera línea
  • \ 2 - los primeros 10 caracteres (en un grupo anidado)
  • un salto de línea
  • \ 3 : los primeros diez caracteres de la línea dos
  • \ 4 - el resto de la segunda línea

Luego construye las dos líneas como \ 1 \ n \ 2 \ 4 - completa la primera línea, salto de línea, primeros 10 caracteres de la primera, resto de la segunda

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top