Commande Bash pour copier avant le curseur et coller après?

24

Je ne sais pas comment formuler cela, mais je me retrouve souvent à taper des commandes comme celle-ci:

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

Habituellement, je tape simplement le chemin deux fois (avec la tabulation terminée) ou je copie et colle le chemin avec le curseur. Existe-t-il un bashfoo qui facilite la saisie?

user1028270
la source
2
Je pense que tu veux dire bash-fu:)
cat

Réponses:

43

Il y a un certain nombre d'astuces (il y en a un double je pense), mais pour cela j'ai tendance à faire

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

qui est étendu à votre commande.

Ceci est connu sous le nom d' expansion d'accolade . Dans le formulaire utilisé ici, l' {}expression spécifie un certain nombre de chaînes séparées par des virgules. Ceux-ci "développent" l' /etc/prog/dir1/myconfig.yml{,.bak}expression entière , remplaçant la {}partie par chaque chaîne à son tour: la chaîne vide, donnant /etc/prog/dir1/myconfig.yml, puis .bakdonnant /etc/prog/dir1/myconfig.yml.bak. Le résultat est

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

Ces expressions peuvent être imbriquées:

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

produit

ab ac ade adf adg

Il existe une variante utilisant des nombres pour produire des séquences:

echo {1..10}

produit

1 2 3 4 5 6 7 8 9 10

et vous pouvez également spécifier l'étape:

echo {0..10..5}

produit

0 5 10
Stephen Kitt
la source
putain c'est doux. Je pensais que je n'étais pas le premier à poser, juste une question délicate à prononcer.
user1028270
Que fait la virgule là-bas?
user1028270
5
Voir Brace Expansion dans le manuel: il sépare les valeurs utilisées dans l'expansion. Ici, les deux valeurs sont la chaîne vide et .bak.
Stephen Kitt
12

L'expansion de l'historique peut être utile pour ce genre de chose (en supposant que l'historique bash est activé).

Dans votre exemple, vous pourriez faire:

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

Ici, le !#fait référence à la ligne actuelle, !#:1fait référence au paramètre 1 sur la ligne actuelle
et !#:1.bakfait référence au paramètre 1 sur la ligne actuelle avec '.bak' collé à la fin.

Lorsque vous avez tapé le spécificateur d'historique, vous pouvez utiliser Ctrl+ Alt+ Epour le développer à sa valeur réelle si vous voulez par exemple revérifier ou modifier le nom de fichier.

La section "History Expansion" des pages de manuel de bash contient plus d'informations.

Caca
la source
8

Semblable à la réponse de progo, mais un peu plus simple: C-wcoupe («tue») le mot à gauche du curseur, l' C-yinsère («tire») à nouveau.

$ 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
la source
2
Notez également que vous pouvez le faire avec plusieurs mots d'affilée (si votre nom de fichier a des espaces, par exemple) et Cy les collera tous, tant que vous n'avez pas déplacé le curseur ou tapé autre chose entre les deux. Tout mélange de commandes de suppression à l' exception des suppressions à un seul caractère (par exemple, retour arrière / del / ctrl-d) fonctionne avec cela.
Random832
6

Vous pouvez également couper-coller (kill-yank en termes emacs / bash) à partir de la ligne de commande pour dupliquer les parties à modifier.

M-dtue vers l'avant jusqu'à la limite du mot, et vous pouvez tuer le texte plusieurs fois et ils sont tous concaténés ensemble en une seule «pâte» pour le tirage. Pratique!

Ramenez tout cela à la ligne de commande au curseur par C-y. Donc, si vous avez une ligne comme celle-ci (l'élément de bloc █ indique la position du curseur):

$ 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

Dans les deux cas, vous préférez le faire, vous familiariser avec ce que bash a à offrir dans le département clé interactif sera bénéfique. http://web.mit.edu/gnu/doc/html/features_7.html

unperson325680
la source
6

Dans tcshou zsh, Alt+Ctrl+_en emacsmode ( copy-prev-wordwidget) insère le dernier mot, donc

cp très-long-path Alt+Ctrl+_.back

basha un copy-backward-wordwidget (qui n'est lié à aucune touche par défaut) mais qui copie uniquement le mot dans le tampon en anneau, vous devez également appuyer sur Ctrl-Y(en emacsmode) pour le retirer. Mais vous pourriez faire:

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

Pour Alt+Ctrl+_faire à la fois le copier / snarf et coller / yank comme dans tcsh/ zsh.

Stéphane Chazelas
la source