Comando Bash para copiar antes del cursor y pegar después?


24

No estoy seguro de cómo redactar esto, pero a menudo me encuentro escribiendo comandos como este:

cp /etc/prog/dir1/myconfig.yml /etc/prog/dir1/myconfig.yml.bak

Por lo general, solo escribo la ruta dos veces (con la finalización de la pestaña) o copiaré y pegaré la ruta con el cursor. ¿Hay algún bashfoo que haga que esto sea más fácil de escribir?


2
Creo que te refieres bash-fu:)
— gato

Respuestas:


43

Hay varios trucos (creo que hay un duplicado que se encuentra), pero por esto tiendo a hacer

cp /etc/prog/dir1/myconfig.yml{,.bak}

que se expande a tus órdenes.

Esto se conoce como expansión de llaves . En la forma utilizada aquí, la {}expresión especifica una serie de cadenas separadas por comas. Estos "expanden" la /etc/prog/dir1/myconfig.yml{,.bak}expresión completa , reemplazando la {}parte con cada cadena a su vez: la cadena vacía, dando /etc/prog/dir1/myconfig.ymly luego .bakdando /etc/prog/dir1/myconfig.yml.bak. El resultado es

cp /etc/prog/dir1/myconfig.yml /etc/prog/dir1/myconfig.yml.bak

Estas expresiones se pueden anidar:

echo a{b,c,d{e,f,g}}

produce

ab ac ade adf adg

Hay una variante que usa números para producir secuencias:

echo {1..10}

produce

1 2 3 4 5 6 7 8 9 10

y también puedes especificar el paso:

echo {0..10..5}

produce

0 5 10

maldita sea eso dulce. Pensé que no era el primero en preguntar, solo una especie de pregunta complicada.
— user1028270

¿Qué hace la coma allí?
— user1028270

55
Consulte Expansión de llaves en el manual: separa los valores utilizados en la expansión. Aquí los dos valores son la cadena vacía y .bak.
— Stephen Kitt

12

La expansión del historial puede ser útil para este tipo de cosas (suponiendo que el historial de bash esté habilitado).

En su ejemplo, podría hacer:

cp /etc/prog/dir1/myconfig.yml !#:1.bak

Aquí, se !#refiere a la línea actual, se !#:1refiere al parámetro 1 en la línea actual
y!#:1.bak refiere al parámetro 1 en la línea actual con '.bak' pegado al final.

Cuando tiene el especificador de historial escrito, puede usar Ctrl+ Alt+E para expandirlo a su valor real si desea, por ejemplo, verificar o modificar el nombre de archivo.

La sección "Expansión del historial" en las páginas de manual de bash tiene más información.


8

Similar a la respuesta de progo, pero algo más simple: C-wcorta ("mata") la palabra a la izquierda del cursor, la C-yinserta ("tira") nuevamente.

$ cp /etc/dir1/myconfig.yml█                              (C-w)
$ cp █                                                    (C-y)
$ cp /etc/dir1/myconfig.yml█                              (space, C-y)
$ cp /etc/dir1/myconfig.yml /etc/dir1/myconfig.yml█       (finish text)
$ cp /etc/dir1/myconfig.yml /etc/dir1/myconfig.yml.bak█

2
También vale la pena señalar que puede hacer esto con varias palabras seguidas (si su nombre de archivo tiene espacios, por ejemplo) y Cy las pegará todas, siempre y cuando no haya movido el cursor o escrito algo más en el medio. Cualquier combinación de comandos de eliminación, excepto las eliminaciones de un solo carácter (por ejemplo, retroceso / del / ctrl-d) funciona con esto.
— Random832

6

También puede cortar y pegar (kill-yank en términos de emacs / bash) desde la línea de comandos para duplicar partes para su edición.

M-dmata hacia adelante hasta el límite de la palabra, y puede matar el texto varias veces y todos se concatenan juntos en una sola 'pegar' para tirar. ¡Conveniente!

Yank todo esto de vuelta a la línea de comandos en el cursor por C-y. Entonces, si tiene una línea como esta (el elemento de bloque █ indica la posición del cursor):

$ cp avb.txt█                 (M-b M-b)
$ cp█avb.txt                  (M-d) kill the word 'avb'
$ cp █.txt                    (C-y) yank it back
$ cp avb█.txt                 (C-e) to the end of line
$ cp avb.txt█                 (C-y) yank it again
$ cp avb.txt avb█             finish the line
$ cp avb.txt avb.foo█

De cualquier manera que prefiera hacerlo, familiarizarse con lo que bash tiene para ofrecer en el departamento de claves interactivas será beneficioso. http://web.mit.edu/gnu/doc/html/features_7.html


6

En tcsho zsh, Alt+Ctrl+_en emacsmodo (copy-prev-word widget) inserta la última palabra, entonces

cp camino muy largo Alt+Ctrl+_.back

bashtiene un copy-backward-wordwidget (no está vinculado a ninguna tecla de forma predeterminada) pero que solo copia la palabra en el búfer de anillo, también deberías presionar Ctrl-Y(en emacsmodo) para tirar de ella. Pero podrías hacer:

bind '"\e[cpw~": copy-backward-word'
bind '"\e\C-_": "\e[cpw~\C-Y"'

Para tener Alt+Ctrl+_tanto copiar / snarf y pegar / tirar como en tcsh/ zsh.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.