Comment utiliser les arguments de la commande précédente?


287

Je sais que Esc+ .vous donne le dernier argument de la dernière commande.

Mais je suis intéressé par le premier argument de la dernière commande. Y a-t-il une liaison clé pour le faire?

Sur les mêmes lignes, existe-t-il un moyen générique d'obtenir le nième argument de la dernière commande? Je sais que dans un script bash, vous pouvez utiliser $0, $1etc., mais ceux-ci ne fonctionnent pas sur la ligne de commande.

Aussi, qu'en est-il de l'itération à travers le 0ème argument des commandes précédentes, comme nous pouvons le faire avec le dernier argument en appuyant continuellement sur Esc+ .?

Réponses:


284

Tout comme M-.(meta-dot ou esc-dot ou alt-dot) est la fonction readline yank-last-arg, M-C-y(meta-control-y ou esc-ctrl-y ou ctrl-alt-y) est la fonction readline yank-nth-arg. Sans préciser n, il tire le premier argument de la commande précédente.

Pour spécifier un argument, appuyez sur Échap et sur un nombre ou maintenez la touche Alt et appuyez sur un nombre. Vous pouvez faire Alt- -pour commencer à spécifier un nombre négatif, puis relâchez Alt et appuyez sur le chiffre (cela comptera à partir de la fin de la liste des arguments.

Exemple:

Entrez la commande suivante

$ echo a b c d e f g
a b c d e f g

Maintenant, à l'invite suivante, tapez echo(avec un espace suivant), puis

Appuyez sur Alt- Ctrl- yet vous verrez maintenant:

$ echo a

sans appuyer Enterencore, procédez comme suit

Appuyez sur Alt- 3 Alt- Ctrl-y

Appuyez sur Alt- - 2 Alt- Ctrl-y

Vous allez maintenant voir:

$ echo ace

Au fait, vous auriez pu mettre le echosur la ligne en sélectionnant l'argument 0:

Appuyez sur Alt- 0 Alt- Ctrl-y

Éditer:

Pour répondre à la question que vous avez ajoutée à votre original:

Vous pouvez appuyer sur Alt- 0puis sur à plusieurs reprises Alt- .pour parcourir les commandes précédentes (arg 0). De même Alt- -puis répéter Alt- .vous permettrait de parcourir les précédents avant-derniers arguments.

S'il n'y a pas d'argument approprié sur une ligne particulière de l'histoire, la cloche sonnera.

S'il existe une combinaison particulière que vous utilisez fréquemment, vous pouvez définir une macro pour qu'une seule touche puisse l'exécuter. Cet exemple rappellera le deuxième argument des commandes précédentes en appuyant sur Alt- Shift- Y. Vous pouvez choisir n'importe quelle touche disponible que vous préférez au lieu de celle-ci. Vous pouvez appuyer dessus à plusieurs reprises pour parcourir les précédents.

Pour l'essayer, entrez la macro à l'invite Bash:

bind '"\eY": "\e2\e."'

Pour le rendre persistant, ajoutez cette ligne à votre ~/.inputrcfichier:

"\eY": "\e2\e."

Malheureusement, cela ne semble pas fonctionner pour l'arg 0 ou les nombres d'arguments négatifs.


14
Lorsque je recherche des raccourcis clavier pour bash / readline, j'aime courir bind -lpet regarder les liaisons actuelles.
Chad Skeeters

1
@ChadSkeeters: Et -s(nouveau dans Bash 4) répertorie les macros créées à l'aide -x.
pause jusqu'à nouvel ordre.

Notez que vous pouvez également utiliser l'argument chiffre avec M-.: Alt-3 Alt-Ctrl-ypar exemple, égal à tenir Altet taper 3.. Si vous tapez 3.plusieurs fois sans le relâcher, Altvous passez par le troisième argument de vos lignes de commande précédentes.
dessert

@dessert: J'en dis autant dans mon deuxième paragraphe, puis je montre un exemple.
pause jusqu'à nouvel ordre.

@ChadSkeeters, merci pour l'avertissement qu'il y aurait des centaines d'entrées! Lol.
jdk1.0

309

!$ obtient le dernier élément de l'argument de ligne de commande précédent.


115
!:3vous obtient le troisième
Matt Dodge

108
! * vous obtient tous
wonton

75
!!vous obtient la dernière commande entière. Utile si vous avez oublié d'utiliser sudo.
Un3qual

43
!:1-2vous obtient tous sauf le dernier des 3 arguments
Tyler Brock

5
Juste un mot d'avertissement - si vous utilisez des arguments combinés comme echo foo{,bar} baz, la commande est enregistrée comme imprimée et se développe ensuite. Avec ce qui précède, l'utilisation de echo !:1after se résout à echo foo{,bar}puis se développe enecho foo foobar
Sean

201

Pour utiliser le premier argument, vous pouvez utiliser !^ou!:1

Exemple:

$ echo a b c d e 
a b c d e
$ echo !^
echo a
a

$ echo a b c d e 
a b c d e
$ echo !:1
echo a
a

Puisque votre question concerne l'utilisation d'autres arguments, voici quelques arguments utiles:

!^      first argument
!$      last argument
!*      all arguments
!:2     second argument

!:2-3   second to third arguments
!:2-$   second to last arguments
!:2*    second to last arguments
!:2-    second to next to last arguments

!:0     the command
!!      repeat the previous line

Les quatre premiers formulaires sont plus souvent utilisés. Le formulaire !:2-est quelque peu contre-intuitif, car il n'inclut pas le dernier argument.


Existe-t-il un moyen d'obtenir l'avant-dernier article? c'est-à-dire obtenir file3de mv file1 file2 file3 target/?
Charlie Harding

3
J'ai beaucoup aimé cette réponse et juste pour être complet, je suggère également d'ajouter une ligne expliquant la syntaxe '! -2' qui vous permet d'accéder à la commande précédente à la commande précédente.
bbv

1
@bbv Aussi pour encore plus d'exhaustivité la commande '! 2' qui vous permet d'accéder à la deuxième entrée de l'historique (si elle est toujours disponible en fonction de vos paramètres d'historique). Utile si vous affichez le numéro d'historique dans chaque invite.
816-8055

53

J'ai tellement aimé la réponse de @larsmans que j'ai dû en savoir plus. Ajouter cette réponse pour aider les autres à trouver la section de la page de manuel et à savoir sur quoi google:

$ man  -P 'less -p ^HISTORY\ EXPANSION' bash
<...>
Word Designators

Word designators are used to select desired words from the event.
A : separates the event specification from the word designator.
It may be omitted if the word designator begins with a ^, $, *, -,
or %.  Words are numbered from the beginning of the line, with the
first word being denoted by 0 (zero).  Words are inserted into the
current line separated by single spaces.

   0 (zero)
          The zeroth word.  For the shell, this is the command word.
   n      The nth word.
   ^      The first argument.  That is, word 1.
   $      The last argument.
   %      The word matched by the most recent ‘?string?’ search.
   x-y    A range of words; ‘-y abbreviates 0-y’.
   *      All of the words but the zeroth.
          This is a synonym for 1-$’.  
          It is not an error to use * if there is just one word in
          the event; the empty string is returned in that case.
   x*     Abbreviates x-$.
   x-     Abbreviates x-$ like x*, but omits the last word.

   If a word designator is supplied without an event
   specification, the previous command is used as the event.

18

! ^ peut être la commande du premier argument. je ne sais pas s'il existe un moyen d'obtenir le nième.


7
c'est!: n comme suggéré ci
Sergiu

Existe-t-il un moyen d'obtenir le n-ième dernier article, comme ça !:n, mais en comptant à partir de la fin plutôt que du début?
Charlie Harding

14

Vous pouvez également obtenir des arguments à partir de n'importe quelle commande de votre historique!


$ echo a b c d e f g
a b c d e f g
$ echo build/libs/jenkins-utils-all-0.1.jar
build/libs/jenkins-utils-all-0.1.jar
$ history | tail -5
  601  echo build/libs/jenkins-utils-all-0.1.jar
  602  history | tail -10
  603  echo a b c d e f g
  604  echo build/libs/jenkins-utils-all-0.1.jar
  605  history | tail -5
$ echo !-3:4
echo d
d
$ echo !604:1
echo build/libs/jenkins-utils-all-0.1.jar
build/libs/jenkins-utils-all-0.1.jar


4

Testé sur Ubuntu 18.04


Pour insérer des arguments précédents:

  • Alt+ .: insère le dernier argument de la dernière commande.
  • Alt+ #+ .: insérer #nième dernier argument de la dernière commande.
  • Alt+ -, #, Alt+ ., Zsh: Alt + -+ #+ .: insert #nth premier argument de la commande précédente.

Sous Linux, vous pouvez répéter les commandes pour revenir dans l'histoire

Exemple:

La dernière commande est:

mv foo bar
  • Alt+ 0+ .: insérer le premier argument de la dernière commande =mv
  • Alt+ 2+ .: insérer le dernier 2ème argument de la dernière commande =foo
  • up, Ctrl+ w: dernière commande sans le dernier mot =mv foo

Raccourcis généraux

  • Ctrl+ w: supprime le dernier mot du curseur
  • Alt+ d: supprime le mot suivant du curseur
  • Ctrl+ k: coupe tout après le curseur
  • Ctrl+ u, zsh: Alt + w: coupe tout avant le curseur
  • zsh: Ctrl + u: coupe la commande entière (En bash vous pouvez combiner Ctrl+ u, Ctrl+ k)
  • Ctrl+ y: coller les caractères préalablement coupés avec Ctrl+ uet Ctrl+k
  • Ctrl+ _: annuler la dernière modification (très utile lorsque vous dépassez Ctrl+ w)
  • Ctrl+ left: passer au dernier mot
  • Ctrl+ right: passer au mot suivant
  • homeou Ctrl+ a: passer au début de la ligne
  • endou Ctrl+ e: passer à la fin de la ligne

Pour parcourir les arguments d'une commande précédente

ne fonctionne que dans zsh

exécuter ou ajouter ceci à votre ~/.zshrc

autoload -Uz copy-earlier-word
zle -N copy-earlier-word
bindkey "^[:" copy-earlier-word

Utilisez maintenant Alt+ .pour revenir en arrière comme vous le souhaitez, puis utilisez Alt+ :pour parcourir les arguments

En supposant que la dernière commande est

echo 1 2 3 4 5
  • Alt+ .:5
  • Alt+ .+ ::4
  • Alt+ .+ :+ ::3
  • Alt+ .+ :+ :+ ::2
  • Alt+ .+ :+ :+ :+ ::1
  • Alt+ .+ :+ :+ :+ :+ ::echo

source: https://stackoverflow.com/a/34861762/3163120

Pour voir tous les raccourcis disponibles

  • frapper: bind -lp
  • zsh: bindkey -L

Je garde cela à jour dans cet essentiel https://gist.github.com/madacol/da38e42d7e45c2949a9f425cc20543e9


1
Alt .sur Zsh sur Mac tape 🤔
André Pena

1
Esc . fonctionne, même si cela ne fonctionne que pour le dernier. Vous ne pouvez pas continuer à taper pour remonter dans le temps. Peut-être que cela vaut la peine de mettre à jour la réponse. Merci beaucoup.
André Pena

Vous pouvez exécuter bindkey -Ldans zsh pour voir tous les raccourcis liés, peut-être que cela aidera à identifier le problème ou même à trouver d'autres commandes utiles. Dans mon cas par exemple: la liaison Alt .est définie comme bindkey "^[." insert-last-word. Ctrl L(pour effacer l'écran) -> bindkey "^L" clear-screen. Alt+Ctrl h-> bindkey "^[^H" backward-kill-word(comme Ctrl wpour supprimer le dernier mot)
Madacol

@Madacol Je peux également voir sur les touches de liaison le mot de copie antérieur mentionné bindkey "^[^_" copy-prev-word
kikeenrique

3

Fondamentalement, il a une utilité pour extraire les arguments précédents (de la commande) .

Par exemple, si la commande suivante est émise:

echo Hello, world how are you today?

alors, ce Hello,sera le premier argument, et today?le sixième , c'est le dernier; ce qui signifie qu'il peut être référencé en tapant:

Alt+6 suivi par Ctrl-Alt-6


Ctrlest traditionnellement désigné comme un caractère de chapeau ^ajouté aux noms des clés, et Altcomme M-c'est le préfixe M eta .

Ainsi, le raccourci ci-dessus peut être redéfini ^Mypour tirer.


En outre, il existe un raccourci de substitution de chapeaux dans la ligne de commande:

echo Hello, world!

^Hello^Bye

Bye, world!

pour remplacer la première chaîne correspondante de la commande précédente , ce qui signifie:

Hello, world! Hello, people!

^Hello^Bye

entraînerait:

Bye, world! Hello, people!

laissant le deuxième match ( hello) inchangé.

Remarque: Ne laissez pas d' espace entre les chapeaux , sinon l'opération ne fonctionnera pas.


Ce qui précède n'est qu'un raccourci pour:

!:s/Hello/Bye

la substitution au niveau de l'événement (*) de la première chaîne trouvée (appariée) dans la commande précédente, tandis que le préfixe de la première partie avec le gcommutateur s'appliquera à l'ensemble de la ligne g lobalement :

echo Hello, world! Hello, people!

!:gs/Hello/Bye

Bye, world! Bye, people!

comme cela se fait habituellement dans d'autres commandes connexes telles que sed, viet dans regex(expression régulière) - une méthode standard pour rechercher ( chaîne de correspondance ).

Non, vous ne pouvez pas faire !:sg/Hello/Byeou !:s/Hello/Bye/gici, c'est la syntaxe !


  • ! est pour les événements; L'événement peut être compris comme une sortie de commande ou une opération effectuée dans l'historique des commandes.

C'est ce que j'ai compris en l'utilisant moi-même et en essayant moi-même des choses à partir de ce que j'ai lu à partir de diverses sources, y compris des pages de manuel, des blogs et des forums.

J'espère qu'il éclaircira de mystérieuses façons de faire bash, le shell Bourne-Again (un jeu sur shshell, qui s'appelle lui-même Bourne shell d'après le nom de famille de son inventeur), ce qui est le shell par défaut dans de nombreuses distributions, y compris les serveurs ( OS de serveur ).


3

! ^ vous donnera le premier paramètre,! $ vous donnera le dernier paramètre,!: n vous obtiendrez le nième élément.


0

La méthode décrite à la fin de la réponse acceptée fonctionne également avec l'argument zéro pour moi. J'ai ces lignes dans mon ~/.inputrc:

"\en": "\e0\e."
"\em": "\e1\e."
"\e,": "\e2\e."

\e2\e.présente l'avantage de \e2\e\C-yfaire défiler les commandes précédentes si elle est pressée à plusieurs reprises au lieu d'insérer plusieurs fois le deuxième argument de la commande précédente.

Pour insérer toute la commande précédente, vous pouvez taper !!\e^. \e^est history-expand-line.


0

Si vous êtes sur un Mac, vous aurez tendance à obtenir des caractères étendus avec ctrl + lettre. J'ai ma clé d'option de barre d'espace droit définie comme méta dans mon terminal (iTerm2) configuré. Cela signifie que j'utilise la touche pour naviguer par mot et extraire les paramètres des commandes précédentes.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.