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?

usuario1028270
fuente
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
Stephen Kitt
fuente
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.

Caca
fuente
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
mindriot
fuente
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)
$ cpavb.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

unperson325680
fuente
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.

Stéphane Chazelas
fuente