Comando Bash para copiar antes do cursor e colar depois?

24

Não tenho certeza de como escrever isso, mas muitas vezes me encontro digitando comandos como este:

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

Normalmente, apenas digito o caminho duas vezes (com a conclusão da guia) ou copio e colo o caminho com o cursor. Existe algum bashfoo que facilita a digitação?

user1028270
fonte
2
Eu acho que você quer dizer bash-fu:)
gato

Respostas:

43

Existem vários truques (acho que existe uma duplicata), mas, por isso, costumo fazer

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

que é expandido para o seu comando.

Isso é conhecido como expansão de chaves . No formulário usado aqui, a {}expressão especifica um número de seqüências de caracteres separadas por vírgulas. Eles "expandem" toda a /etc/prog/dir1/myconfig.yml{,.bak}expressão, substituindo a {}parte por cada sequência: a sequência vazia, dando /etc/prog/dir1/myconfig.ymle .bak, em seguida , dando /etc/prog/dir1/myconfig.yml.bak. O resultado é

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

Essas expressões podem ser aninhadas:

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

produz

ab ac ade adf adg

Há uma variante usando números para produzir sequências:

echo {1..10}

produz

1 2 3 4 5 6 7 8 9 10

e você também pode especificar a etapa:

echo {0..10..5}

produz

0 5 10
Stephen Kitt
fonte
caramba, isso é doce. Achei que não era a primeira a perguntar, apenas uma espécie de pergunta complicada.
user1028270
O que a vírgula faz lá?
user1028270
5
Consulte Expansão de chaves no manual: ele separa os valores usados ​​na expansão. Aqui os dois valores são a string vazia e .bak.
Stephen Kitt
12

A expansão do histórico pode ser útil para esse tipo de coisa (supondo que o histórico do bash esteja ativado).

No seu exemplo, você pode fazer:

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

Aqui, !#refere-se à linha atual, !#:1refere-se ao parâmetro 1 na linha atual
e !#:1.bakrefere-se ao parâmetro 1 na linha atual com '.bak' pregado no final.

Quando você digitar o especificador de histórico, poderá usar Ctrl+ Alt+ Epara expandi-lo para seu valor real, se desejar, por exemplo, verificar ou modificar o nome do arquivo.

A seção "Expansão do histórico" nas páginas do manual do bash tem mais informações.

Pooping
fonte
8

Semelhante à resposta do progo, mas um pouco mais simples: C-wcorta ("mata") a palavra à esquerda do cursor, C-yinsere ("puxa") novamente.

$ 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
fonte
2
Também é importante notar que você pode fazer isso com várias palavras seguidas (se o seu nome de arquivo tiver espaços, por exemplo) e o Cy colará todas elas, desde que você não tenha movido o cursor ou digitado qualquer outra coisa no meio. Qualquer combinação de comandos de exclusão, exceto exclusões de um caractere (por exemplo, backspace / del / ctrl-d) funciona com isso.
Random832
6

Você também pode copiar e colar (kill-yank em termos do emacs / bash) na linha de comando para duplicar partes para edição.

M-dmata para a frente até o limite da palavra, e você pode matar o texto várias vezes e todos são concatenados juntos em um único 'colar' para puxar. Conveniente!

Coloque tudo isso de volta na linha de comando no cursor por C-y. Portanto, se você tem uma linha como esta (o elemento de bloco █ indica a posição do 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 qualquer maneira que você preferir, familiarizar-se com o que o bash tem a oferecer no departamento de chaves interativas será benéfico. http://web.mit.edu/gnu/doc/html/features_7.html

unperson325680
fonte
6

No modo tcshou zsh, Alt+Ctrl+_no emacsmodo ( copy-prev-wordwidget) insere a última palavra, portanto

cp caminho muito longo Alt+Ctrl+_.back

bashpossui um copy-backward-wordwidget (não vinculado a nenhuma tecla por padrão), mas que apenas copia a palavra no buffer de toque, você também deve pressionar Ctrl-Y(no emacsmodo) para puxá-lo. Mas você poderia fazer:

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

Para Alt+Ctrl+_fazer a cópia / snarf e colar / puxar como em tcsh/ zsh.

Stéphane Chazelas
fonte