Copie y pegue contenido de un archivo a otro archivo en vi

256

Estoy trabajando con dos archivos y necesito copiar algunas líneas de un archivo y pegarlas en otro archivo. Sé cómo copiar (yy) y pegar (p) en el mismo archivo. Pero eso no funciona para diferentes archivos. ¿Cómo se hace esto?

Además, ¿hay alguna forma de cortar y pegar? He intentado buscar en Google, pero la mayoría de los recursos solo hablan de copiar y pegar.

macha
fuente
¿Estás seguro de que esto no funciona? Lo uso con bastante frecuencia para copiar líneas entre archivos.
sjngm
Bueno, cuando estoy haciendo eso, solo obtengo una comilla.
macha
44
El comando dd funciona como cortar.
Martin Stålberg

Respuestas:

218

Como ya sabe cómo cortar / tirar texto, aquí hay algunas ideas para pegarlo de nuevo en otro archivo:

  • Edite el primer archivo, tirando del texto que desee. Luego abra su segundo archivo desde vi ( :e /path/to/other/file) y péguelo
  • Abra ambos archivos juntos en una ventana dividida y navegue entre ellos usando Ctrl+ w, Up/ Downo bien:

    • vi -o /path/to/file1 /path/to/file2
    • Desde dentro del primer archivo, Ctrl+ w,s
Adam Batkin
fuente
Tengo dos ventanas de masilla abiertas, primero estoy haciendo "v para el modo visual y luego selecciono todas las líneas y hago una" y "para tirar, no estoy haciendo una pestaña alt + para acceder al otro archivo y cuando lo hago una "p" para el puesto, sólo se imprime una comilla.
macha
10
Si está trabajando con 2 ventanas de masilla, debe usar la forma de copiar / pegar masilla / ventanas. Eso es fácil. Marque las cosas que desea copiar con el mouse (no tiene que hacer nada más, el texto marcado ahora se copia en el portapapeles). Cambie a su otra ventana de masilla. Ingrese al modo de inserción en vim (presione i). Presione el botón derecho del mouse: el mouse derecho en una ventana de masilla pegará lo que esté en el portapapeles.
nos
3
Lo que está haciendo no funcionará: Yanking en vi no colocará el texto en su portapapeles de Windows, y el búfer de extracción no se comparte entre instancias vim abiertas.
Adam Batkin
1
No entiendo por qué se supone que el último punto de hacerlo: * Desde dentro del primer archivo, Ctrl+ w, s.
svassr
1
para mí dividió la ventana pero abrió exactamente el mismo archivo. ¿Cómo eliges entonces qué archivo abrir? He visto el comando :sp myfileque se divide horizontalmente y abre el archivo especificado, pero ¿cómo lo haría si prefiero dividir la ventana verticalmente?
svassr
50

Si está utilizando Vim en Windows, puede obtener acceso al portapapeles (copiar / pegar MS) usando:

"*dd - cortar una línea (o 3dd para cortar tres líneas)

"*yy - copie una línea (o 3yy para copiar tres líneas)

"*p - pegar línea (s) en línea después del cursor

"*P - pegar línea (s) en línea antes del cursor

Le permite pegar entre ventanas Vim separadas o entre aplicaciones Vim y PC ( Bloc de notas , Microsoft Word , etc.).

JayG
fuente
17
Use +como registro del portapapeles del sistema multiplataforma (Windows y Linux) vs. *, que es solo Windows ( +funciona igual en Windows que *).
Stephen Swensen el
42

Use las variaciones de me dgusta ddpara cortar.

Para escribir un rango de líneas en otro archivo puede usar:

:<n>,<m> w filename

Donde <n>y <m>son números (o símbolos) que designan un rango de líneas.

Para usar el portapapeles del escritorio, eche un vistazo a los +gcomandos.

Apalala
fuente
Para hacer esto con marcas, cree dos marcas (a y b, por ejemplo) alrededor del texto que desea escribir en un archivo: mover a la primera línea ma, mover a la última línea mb,. Luego anteponga un 'a la letra de la marca cuando esté usando el comando anterior::'a,'b w filename
EchoLynx
¡Gran solución para gamas de líneas amplias!
Yasin Okumuş
29

Puede abrir el otro archivo y escribir :r file_to_be_copied_from. O puedes amortiguar. O vaya al primer archivo, vaya a la línea que desea copiar, escriba "qY, vaya al archivo que desea pegar y escriba "qP.

"buffer_name, copia en el buffer. YSe tira y Pse pone. ¡Espero que ayude!

Win Man
fuente
¡Gracias! Esto me ayudó muchísimo
Atsushi Yamamoto
28

Aquí hay una forma de hacerlo;

  • Inicie Vim y abra el archivo1, que es el archivo en el que está trabajando.
  • :e file2 que mostrará file2, el archivo del que desea copiar las líneas.
  • Localice las líneas que desea copiar. Si son tres líneas, golpeas3yy
  • :b1 esto cambiará al búfer 1, donde file1 es
  • averigua dónde quieres insertar las líneas que tiraste y presiona p

También podría tener ambos archivos visibles. Divida la pantalla con, por ejemplo, Ctrl+ w s.

En cuanto al corte, dcorta y coloca las cosas cortadas en el búfer de extracción. dd"cortará" una línea.

nos
fuente
2
fuera de tema: ¿cómo obtengo esas cosas como botones de teclado?
Eckes
¿Qué pasa con los dos archivos en dos servidores ssh diferentes, en los que el mismo cliente ssh'es en dos terminales diferentes en Linux / MacOS? Quiero decir, no hay masilla para usar, y los dos archivos no se pueden abrir en la misma sesión vi en una terminal.
Qiang Xu
1
Si el cliente puede ingresar a dos servidores, también puede usar scp o sftp para esos dos servidores. Entonces, la forma más rápida es simplemente copiar el archivo de un servidor a otro para que residan en el mismo servidor, editar esos archivos como se describe y copiar el archivo nuevamente al otro servidor cuando sea necesario.
nos
16

Estas son todas excelentes sugerencias, pero si conoce la ubicación del texto en otro archivo, use sed con facilidad. :r! sed -n '1,10 p' < input_file.txtEsto insertará 10 líneas en un archivo ya abierto en la posición actual del cursor.

malik
fuente
Curiosamente obtuve un código de salida de 1 cuando ejecuté esto desafortunadamente en os x, no estoy seguro de por qué.
jayunit100
1
Gracias por esta sugerencia! Usé head en lugar de sed porque quería las primeras 2 líneas::r ! head -n2 file.py
Federico Ponzi
7

Mientras edita el archivo, marque donde desea que se usen el inicio y el final

ma- establece la amarca

mb- establece la bmarca

Luego, para copiar eso en otro archivo, simplemente use el wcomando:

:'a,'bw /name/of/output/file.txt
vman
fuente
7

Actualización 2017-05:

Acabo de descubrir que si agrega la siguiente línea en su archivo vimrc,

establecer portapapeles = sin nombre

entonces Vim está usando el portapapeles del sistema.


Acabo de encontrar que la forma de tirar no funcionará en la forma en que copie contenido entre diferentes ventanas de instancia de Vim. (Al menos, no funciona según mi conocimiento de Vim. No sé si hay otra forma de permitir que funcione).

La forma de tirar solo funciona en la forma en que se abren varios archivos en la misma ventana de acuerdo con mi prueba.

Si desea hacer eso, será mejor que use la forma de cortar y copiar del sistema operativo, como Ctrl+ x, Ctrl+ c(en Windows).

Lichader
fuente
5

Estos remaps funcionan como un encanto para mí:

vmap <C-c> "*y     " Yank current selection into system clipboard
nmap <C-c> "*Y     " Yank current line into system clipboard (if nothing is selected)
nmap <C-v> "*p     " Paste from system clipboard

Entonces, cuando estoy en modo visual, selecciono las líneas que quiero y presiono Ctrl+ cy luego Ctrl+ vpara insertar el texto en el archivo receptor. Podrías usar "* y también, pero creo que esto es difícil de recordar a veces.

Esto también es útil para copiar texto de Vim al portapapeles.

Fuente: copiar y pegar entre sesiones utilizando un archivo temporal

rovitulli
fuente
4

Copiar texto entre dos buffers (== archivos) que se abren en la misma instancia de Vim no es un problema:

Simplemente dar un tirón en un buffer con y(suponiendo que haya marcado un área de copia en modo visual antes), y luego pegar en la otra memoria intermedia con p. También funciona con diferentes pestañas siempre que estén en la misma instancia de Vim.

Cómo abrir dos archivos en la misma instancia de Vim depende de su sistema:

  • En Win32, hay una opción en el menú contextual que dice Editar con un vim si selecciona dos o más archivos
  • Cuando estás en la consola, puedes lograrlo con vim file1 file2
  • Si usa Vim como editor para otra herramienta, asegúrese de especificar la --remote-silentopción para asegurarse de que todos los archivos se abran en la misma instancia

Si abrió los dos archivos en dos instancias diferentes de Vim, entonces debe ir con el portapapeles del sistema: en la primera instancia de Vim, tire el texto en el portapapeles del sistema usando "+y(nuevamente, marque el área que se va a tirar en modo visual antes ), y luego ir a la segunda Vim y pegar el portapapeles existe: "+p.

Eckes
fuente
: tabedit filename se puede usar para abrir el archivo de destino y luego simplemente p para pegar sus líneas. Creo que es más rápido
jabalv
4

Objetivo : guardar una parte de un archivo en otro archivo.

Solución :

  1. Seleccione el texto que desea guardar:
    • Posicione el cursor donde desea comenzar la selección
    • Presione vpara seleccionar caracteres O mayúsculas Vpara seleccionar líneas enteras
    • Mueva el cursor al final de lo que desea seleccionar
  2. Guarde el texto seleccionado en el nuevo archivo. Escriba :wSpacey el nombre del nuevo archivo. En realidad verás

    :'<,'>w new.txt

    Entonces presione Enter

Lu55
fuente
¿Cómo pegar desde el archivo temporal?
Vineet
3

Mi escenario era que necesito copiar n número de líneas en el medio, n desconocido, del archivo 1 al archivo 2.

:'a,'bw /name/of/output/file.txt
Shyam S
fuente
2
  1. Asegúrese de tener la versión de Vim compilada con soporte para portapapeles
    • :echo has('clipboard') debería volver 1
    • si regresa 0(por ejemplo, Mac OS X, al menos v10.11 (El Capitan), v10.9 (Mavericks) y v10.8 (Mountain Lion), viene con una versión Vim que no admite el portapapeles), debe instalar un Versión Vim con soporte para portapapeles, digamos vía brew install vim(no olvides reiniciar tus terminales después de la instalación)
  2. Ingrese a un modo visual ( V- multilínea, v- simple o Ctrlv- bloque visual)
  3. Seleccione la (s) línea (s) que desea copiar
  4. "*y - copiar seleccionado
  5. "*p - pegar copiado

PD:

  • puede reemplazar los pasos 2 a 5 con las instrucciones de la respuesta de JayG , si necesita copiar y pegar una sola línea
  • para facilitar la selección de líneas, puede agregar set mouse+=aa su .vimrc- le permitirá seleccionar líneas en Vim usando el mouse, sin seleccionar elementos extraños (como números de línea, etc.) AVISO: bloqueará la capacidad de copiar texto seleccionado por el mouse al portapapeles del sistema de Vim .
Peter Mortensen
fuente
1

Ejemplo: archivo A y archivo B: comience en el archivo A en la línea 25, copie 50 líneas y péguelo en el archivo B

fileA

Goto 25th line

25G

copy 50 lines into buffer v

"v50yy

Goto fileB

:e fileB

Goto line 10

10G    

paste contents of buffer v
"vp
Brenda
fuente
1

La siguiente opción funciona la mayor parte del tiempo y también para pegarla más tarde.

 "xnyy
x - buffer name
n - number of line to Yank - optional

Las líneas arrancadas se almacenarán en el búfer 'x'. Se puede usar en cualquier lugar de la edición.

Para pegar líneas en el otro archivo,

:e filename&location

Ejemplo: escriba el siguiente comando en la edición actual

:e /u/test/Test2.sh
and paste using "xP
P - before cursor
p - after cursor

Operación completa

abrir archivo 1:

vi Test1.sh

a10yy

-Yanked 10 lines

-ahora abra el segundo archivo de la edición actual

*:e /u/test/Test2.sh*

-mover el cursor a la línea donde tiene que pegar

*"ap*

--Las líneas del búfer '*a*'se copiarán después de la posición actual del cursor

Raams
fuente
1

Si desea copiar una parte de un archivo y pegar ese contenido en el medio de otro archivo, puede hacerlo de esta manera.

:linenumber,linenumber write newfile

Ejemplo:

:2,34 write temp1

O

:'mark, 'mark write newfile

Ejemplo:

:'a,'b write temp1

Ahora las líneas se copian a otro archivo. Si desea eliminar esas líneas después de copiar, puede hacer

:linenumber1,linenumber2 d

O

:'mark1,'mark2 d

Ahora, ve a otro archivo. Luego, mantenga el cursor en la línea donde desea pegar.

Tipo

:r!cat temp1

Ahora, el contenido del archivo temporal se pega aquí. Puede eliminar el archivo temporal de la línea de comando en sí, después de pegar el contenido.

:!rm temp1

Esto ayudaría si quisiera copiar y pegar varias veces.

SibiCoder
fuente
0

Otra forma podría ser abrir los dos archivos en dos buffers divididos y usar el siguiente "fragmento" después de la selección visual de las líneas de interés.

:vnoremap <F4> :y<CR><C-W>Wr<Esc>p
Thorsten
fuente
0

Ingrese al modo de comando y ejecute

:r! sed -n '<start_line_num>, <end_line_num> p' file_to_extract_text_from

Por ejemplo, para extraer líneas 20-30del filenamearchivo abierto actualmente

:r! sed -n '20, 30p' filename
Anthony Awuley
fuente