Comment changer rapidement le premier mot d'une commande Bash?

44

Je voudrais améliorer un peu mon flux de travail avec Bash, et je réalise que je veux souvent exécuter la même commande sur un exécutable différent.

Quelques exemples:

Git (où je voudrais changer rapidement le deuxième mot):

git diff     foo/bar.c
git checkout foo/bar.c

Cat / rm (où seul le premier mot doit être changé):

cat foo/is/a/very/long/path/to/bar.c
rm  foo/is/a/very/long/path/to/bar.c

Je sais que je peux frapper Ctrl+ apuis Delpour enlever le premier mot, mais je me demande s'il y a un moyen plus rapide de le faire.

maintenant
la source
Honnêtement, je pense qu'il est plus sûr d'utiliser simplement Ctrl + a et de supprimer. Ce n'est certainement pas très lent.
agweber

Réponses:

56

!$ se développe jusqu'au dernier mot de votre commande précédente.

Alors tu pourrais faire:

cat foo/is/a/very/long/path/to/bar.c

rm !$

ou:

git diff foo/bar.c

git checkout !$

Il est arrivé que vos exemples ne répètent que le dernier mot, de sorte que tout !$a bien fonctionné. Si vous vouliez répéter un grand nombre d'arguments et que vous souhaitiez simplement modifier le premier mot, vous pouvez utiliser le même mot !*, qui s'étend à tous les mots de la commande précédente, à l'exception du zéro.

Voir la section "EXTENSION DE L'HISTORIQUE" de la bashpage de manuel. Il y a beaucoup de flexibilité là-bas.

Spiff
la source
16
Juste et convenable. Je voudrais seulement mettre un avertissement : avec !$vous n'avez pas de contrôle visuel complet de la ligne que vous exécutez . Cela peut parfois être dangereux. Surtout si vous vous exposez à une erreur Cela prend du historyquoi élargir. Donc, si vous écrivez la dernière commande avec un espace vide au début, cette commande ne se terminera probablement pas dans l'historique. Lorsque vous exécuterez votre nouvelle commande avec !$le shell, les paramètres ne seront pas repris de la dernière ligne de commande tapée, mais uniquement du dernier de l'historique. Voici les mêmes mots.
Hastur
1
@Hastur Vous pouvez configurer votre shell pour développer l'historique sur l'onglet ou à l'entrée pour éviter les accidents.
Slhck
2
@Hastur, c'est pourquoi vous devez appuyer deux fois sur l'intro en zsh (promotion sans vergogne)
Braiam
@Hastur - Lorsque j'ai le moindre doute sur ce qui va se passer ou que je réalise tardivement que je dois faire autre chose avant d'exécuter quelque chose de long que je viens de taper, je vais au début de la ligne et ajoute un #ou une echo afin que je puisse voyez-le et il entre dans l'histoire pour que je puisse le récupérer immédiatement et le réexécuter sans le préfixe de désactivation.
Joe
28

Ctrl+ apour aller au début de la ligne, puis Alt+ dpour supprimer le premier mot.

jjlin
la source
9
Le raccourci du mot supprimer est en fait Meta + d, et Meta est généralement mappé sur Alt sur des machines Linux. Sur les plates-formes où ce n'est pas le cas, une alternative pour obtenir le modificateur Meta consiste à utiliser le caractère d'échappement comme préfixe. Voir en.wikipedia.org/wiki/Meta_key
Gustavo Giráldez le
2
@ GustavoGiráldez si vous voulez aller en profondeur, alors Meta+Dn'est valide que si emacsest activé (via set -o emacsou simplement par défaut). Cela ne fonctionnera pas dans l' éditeur inférieur -mode ou s'il emacsest désactivé.
TC1
Dans de nombreux terminaux (car il s'agit d'un terminal et non d'un Bash), la touche home va également au début d'une ligne. De nombreux ordinateurs portables mappent Fn + Gauche sur la touche d'accueil. De même, la touche de fin ira généralement à la fin de la ligne. Je n'ai pas encore utilisé d'émulateur de terminal qui ne prend pas en charge ces raccourcis clavier.
Kat
1
@ Mike D'autre part, C-aet M-dsont beaucoup plus rapides à taper si vos mains sont déjà en position de frappe.
Jjlin
@ Mike Ceci est une chose bash. Tapez catet comparez ce que vous obtenez lorsque vous appuyez sur Accueil ( ^[[Hici) et sur Ctrl + a ( ^A).
Jonas Schäfer
17

Je ne sais pas si ce serait effectivement plus rapide ou pas, mais voir cet article, en particulier le point # .3:

  1. Remplace une chaîne de la commande précédente en utilisant ^ str1 ^ str2 ^

Dans l'exemple suivant, nous avons d'abord exécuté la commande ls pour vérifier un fichier. Plus tard, nous avons réalisé que nous voulions afficher le contenu du fichier. Au lieu de taper à nouveau le nom de fichier complet, nous pouvons simplement remplacer «ls» dans la commande précédente par «cat», comme indiqué ci-dessous.

$ ls /etc/cron.daily/logrotate

$ ^ls^cat^
cat /etc/cron.daily/logrotate
Benguin
la source
15

Alt+.

Si vous avez seulement besoin de répéter la dernière partie d'une des commandes précédentes, vous pouvez utiliser Alt+ .pour coller le dernier argument extrait de la dernière ligne de l'historique.

Si vous appuyez plus d'une fois, ce que vous venez de coller sera remplacé par le dernier argument de la ligne avant ...

Par exemple, si les 2 dernières commandes étaient:

cat foo/is/a/very/long/path/to/bar.c
pico foo/is/a/very/long/path/to/SomeWhereElse.c

Dans le shell, j'écris rmet j'appuie sur Alt+, .il apparaîtra:

rm foo/is/a/very/long/path/to/SomeWhereElse.c

si j'appuie à nouveau Alt+ .il apparaîtra à la place

rm foo/is/a/very/long/path/to/bar.c

etc...

Hastur
la source
Je ne sais pas pourquoi mais cela ne fonctionne pas sur la console de mon Mac.
lulalala
Ici, il y a les raccourcis clavier avec lesquels il est connu de travailler bash. BTW Êtes-vous sûr que vous utilisez bash en tant que shell ?
Hastur
1
Je suppose que c'est un truc Mac. Quand je tape ce que je reçois
lulalala
12

En plus de @jjlin answer, les conseils suivants pourraient vous intéresser:

  • Ctrl+ wsupprime le mot à votre gauche
  • Ctrl+ ksupprime du curseur jusqu'à la fin de la ligne de commande
  • Ctrl+ usupprime du curseur au début de la ligne de commande
  • Alt+ bdéplace le curseur d'un mot en arrière
  • Alt+ fdéplace le curseur d'un mot
  • $_ contient le dernier argument de la ligne de commande précédente

Pour plus d'informations à ce sujet, consultez la section "Noms des commandes Readline" de la bashpage de manuel.

par exemple:

cat foo/is/a/very/long/path/to/bar.c
rm $_
maiki
la source
Ce sont de bons conseils, mais ils ne répondent pas à la question.
Slhck
@slhck IMHO c'est parce que le titre de la question ne correspond pas aux exemples donnés. Si nous nous concentrons sur les exemples, comme je l’ai fait, le titre devrait être "Comment changer rapidement un mot dans une commande bash?" . C'est aussi pourquoi ma réponse est "en plus de celle de @jjlin". Mais je suppose que la question devrait être clarifiée.
maiki
L'OP veut toujours supprimer (échanger) les premiers nmots de la commande, avec n = 1dans le premier exemple et n = 2dans le second. La réponse de jjlin montre comment supprimer le premier mot (et en réappliquant le raccourci, supprimer jusqu'à nmots). Votre réponse répertorie quelques raccourcis Bash (qui sont en effet utiles), mais aucun d’eux n’est un moyen efficace de supprimer les premiers nmots.
Slhck
Hm, en relisant, le $_paramètre fonctionnerait probablement s'il n'y avait qu'un seul argument (c'est-à-dire si n = m - 1mest le nombre total d'arguments). Le reste des raccourcis est cependant sans rapport avec la question.
Slhck
@slhck Par souci d'argumentation, j'ai lu le premier exemple: "remplace le deuxième mot" :-)
maiki
8

Si vous maîtrisez vi, vous pouvez activer les liaisons vi dans bash (la plupart des shells?) En utilisant la commande set -o vi. Ensuite, vous pouvez utiliser les touches vi normales pour éditer votre commande. Dans votre premier exemple, vous pouvez ^wcwsupprimer "diff", puis le changer en caisse.

Il ne vaut peut-être pas la peine d'apprendre les raccourcis clavier vi juste pour éditer la ligne de commande, mais si vous les connaissez déjà, c'est un booster de productivité.

Chaosed0
la source
J'ai appris sur kornshell, c'est set -o viainsi que j'ai vécu! Je le fais même dans mes invites bash aussi.
bgStack15
bindkey -vpour zsh. Esc 0 c w
user530873
6

Il y a beaucoup de façons de peler ce chat!

Pour remplacer une chaîne spécifique, ^old^new^extraprenez votre commande précédente, remplacez oldpar new, et ajoutez extra. Vous pouvez vous arrêter aussi tôt que vous le souhaitez. Par exemple, ^oldva remplacer oldpar la chaîne vide et ajouter la chaîne vide (essentiellement supprimer oldet ne plus rien faire).

1. ^diff^checkout
2. ^cat^rm

Variante particulièrement utile de ceci:

for i in `seq 1 10`; do echo something complicated; done
# inspect the output to see if it looks right
^echo

Pour remplacer un mot spécifique, vous pouvez utiliser !m:n-ppour faire référence à des mots nvia pla commande m(utilisez des nombres négatifs pour compter à partir de la commande en cours). Vous pouvez omettre la -ppartie pour faire référence à un seul mot et omettre la :m-ppartie pour faire référence à une commande entière. Des formes spéciales !!pour !-1, !$pour le dernier mot de la commande précédente et !*pour les arguments (tous sauf les mots 0) de la commande précédente sont assez pratiques.

1. !!:0 checkout !!:2-
2. rm !*

J'utilise souvent les deux; zsh est particulièrement agréable ici, car cliquer sur onglet élargira le contenu cryptique pour vous assurer que vous avez bien compris.

Il y a aussi tellement de façons de faire cela avec l'édition en ligne. Lisez sur les raccourcis clavier de votre shell.

Daniel Wagner
la source
-2

La plupart des programmes terminaux supportent ...

  • Appuyez sur <Up-Arrow>si nécessaire pour afficher à nouveau l'une des lignes de commande précédentes de l'historique.
    • Appuyez <Down-Arrow>autant de fois que nécessaire pour avancer dans la liste d'historique.
  • Appuyez sur <Left-Arrow>au besoin pour déplacer le curseur à la fin du deuxième mot.
  • Appuyez sur <Backspace>au besoin pour effacer le deuxième mot.
  • Tapez le deuxième mot de remplacement.
    • Appuyez sur <Right-Arrow>/ <Left-Arrow>au besoin pour vous repositionner pour d'autres modifications.
  • Hit <RETURN>pour exécuter la commande

Si la ligne de commande souhaitée n'est pas récente, effectuez une recherche inversée <Ctrl-r>comme décrit à la question ...
Existe-t-il un moyen d'utiliser ctrl-r après avoir tapé une partie de la commande dans bash?
Puis éditez via les flèches au besoin.

DocSalvager
la source
-3

Ce que je fais (Ubuntu / bash):

1) Arrow uphé pour revenir à la commande précédente
2) Hometouche pour revenir au début
3) Modifiez la commande si nécessaire.

Idiot-proof et particulièrement utile pour les commandes multilignes.

Vorac
la source