Wie verwende ich Argumente aus dem vorherigen Befehl?


287

Ich weiß, dass Esc+ .Ihnen das letzte Argument des letzten Befehls gibt.

Aber ich interessiere mich für das erste Argument des letzten Befehls. Gibt es dafür eine Schlüsselbindung?

Gibt es in den gleichen Zeilen eine generische Möglichkeit, das n-te Argument aus dem letzten Befehl zu erhalten? Ich weiß , dass in einem Bash - Skript, die Sie verwenden können $0, $1usw., aber diese funktionieren nicht auf der Kommandozeile.

Wie wäre es auch mit dem Durchlaufen des 0. Arguments vorheriger Befehle, wie wir es mit dem letzten Argument tun können, indem wir kontinuierlich Esc+ drücken .?

Antworten:


284

So wie M-.(Meta-Punkt oder Esc-Punkt oder Alt-Punkt) die Readline-Funktion ist yank-last-arg, ist M-C-y(Meta-Control-Y oder Esc-Strg-Y oder Strg-Alt-Y) die Readline-Funktion yank-nth-arg. Ohne Angabe nwird das erste Argument des vorherigen Befehls gezogen.

Um ein Argument anzugeben, drücken Sie Escape und eine Zahl oder halten Sie Alt gedrückt und drücken Sie eine Zahl. Sie können Folgendes tun Alt: -Um mit der Angabe einer negativen Zahl zu beginnen, lassen Sie die Alt-Taste los und drücken Sie die Ziffer (dies zählt ab dem Ende der Liste der Argumente.

Beispiel:

Geben Sie den folgenden Befehl ein

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

Geben Sie nun bei der nächsten Eingabeaufforderung echo(mit einem folgenden Leerzeichen) ein

Drücken Sie Alt- Ctrl- yund Sie sehen jetzt:

$ echo a

Gehen Sie Enterwie folgt vor, ohne noch zu drücken

Drücken Sie Alt- 3 Alt- Ctrl-y

Drücken Sie Alt- - 2 Alt- Ctrl-y

Jetzt werden Sie sehen:

$ echo ace

Übrigens hätten Sie das echoin die Zeile setzen können, indem Sie das Argument 0 ausgewählt haben:

Drücken Sie Alt- 0 Alt- Ctrl-y

Bearbeiten:

So beantworten Sie die Frage, die Sie Ihrem Original hinzugefügt haben:

Sie können drücken Alt- und 0dann wiederholt drücken Alt- ., um die vorherigen Befehle zu durchlaufen (arg 0). In ähnlicher Weise können Sie Alt- -dann wiederholen Alt- .die vorherigen vorletzten Argumente durchgehen.

Wenn es in einer bestimmten Zeile in der Geschichte kein geeignetes Argument gibt, wird die Glocke geläutet.

Wenn Sie eine bestimmte Kombination häufig verwenden, können Sie ein Makro so definieren, dass es mit einem Tastendruck ausgeführt wird. In diesem Beispiel wird das zweite Argument aus früheren Befehlen durch Drücken von Alt- Shift- abgerufen Y. Sie können einen beliebigen verfügbaren Tastenanschlag anstelle dieses auswählen. Sie können wiederholt darauf drücken, um die vorherigen zu durchlaufen.

Geben Sie zum Ausprobieren das Makro an einer Bash-Eingabeaufforderung ein:

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

Fügen Sie Ihrer ~/.inputrcDatei diese Zeile hinzu, um sie dauerhaft zu machen :

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

Leider scheint dies für arg 0 oder negative Argumentnummern nicht zu funktionieren.


14
Wenn ich nach Tastaturkürzeln für Bash / Readline bind -lpsuche, laufe ich gerne und schaue mir die aktuellen Bindungen an.
Chad Skeeters

1
@ChadSkeeters: Und -s(neu in Bash 4) listet Makros auf, die mit erstellt wurden -x.
Bis auf weiteres angehalten.

Beachten Sie, dass Sie das Ziffernargument auch mit verwenden können M-.: Alt-3 Alt-Ctrl-yBeispiel: Halten Altund Tippen 3.. Wenn Sie dies 3.mehrmals eingeben, ohne es freizugeben Alt, gehen Sie die dritten Argumente Ihrer vorherigen Befehlszeilen durch.
Nachtisch

@dessert: Das sage ich in meinem zweiten Absatz und zeige dann ein Beispiel.
Bis auf weiteres angehalten.

@ChadSkeeters, danke für die Warnung, dass es Hunderte von Einträgen geben würde ! Lol.
jdk1.0

309

!$ Ruft das letzte Element des vorherigen Befehlszeilenarguments ab.


115
!:3holt dir den dritten
Matt Dodge

108
! * bekommt Sie alle em
Wonton

75
!!holt dir den gesamten letzten Befehl. Nützlich, wenn Sie vergessen haben, zu verwenden sudo.
Un3qual

43
!:1-2bekommt Sie alle bis auf das letzte von 3 Argumenten
Tyler Brock

5
Nur ein Wort der Warnung - wenn Sie kombinierte Argumente wie verwenden echo foo{,bar} baz, wird der Befehl als gedruckt aufgezeichnet und anschließend erweitert. Mit dem oben genannten wird die Verwendung von echo !:1after in aufgelöst echo foo{,bar}und dann erweitertecho foo foobar
Sean

200

Um das erste Argument zu verwenden, können Sie !^oder verwenden!:1

Beispiel:

$ 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

Da es bei Ihrer Frage um die Verwendung anderer Argumente geht, sind hier einige nützliche:

!^      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

Die ersten vier Formen werden häufiger verwendet. Das Formular !:2-ist etwas kontraintuitiv, da es nicht das letzte Argument enthält.


Gibt es eine Möglichkeit, den vorletzten Artikel zu erhalten? dh erhalten file3aus mv file1 file2 file3 target/?
Charlie Harding

3
Diese Antwort hat mir sehr gut gefallen, und der Vollständigkeit halber schlage ich vor, auch eine Zeile mit der Syntax '! -2' hinzuzufügen, mit der Sie auf den vorherigen Befehl zugreifen können.
BBV

1
@bbv Der Vollständigkeit halber auch den Befehl '! 2', mit dem Sie auf den zweiten Eintrag im Verlauf zugreifen können (sofern dieser abhängig von Ihren Verlaufseinstellungen noch verfügbar ist). Nützlich, wenn Sie die Verlaufsnummer in jeder Eingabeaufforderung anzeigen.
816-8055

53

Ich mochte @larsmans Antwort so sehr, dass ich mehr lernen musste. Hinzufügen dieser Antwort, um anderen zu helfen, den Manpage-Bereich zu finden und zu wissen, wonach sie googeln sollen:

$ 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

! ^ kann der Befehl für das erste Argument sein. Ich bin mir nicht sicher, ob es einen Weg gibt, den n-ten zu bekommen.


7
es ist !: n wie oben vorgeschlagen
Sergiu

Gibt es eine Möglichkeit, den n-ten letzten Gegenstand zu erhalten !:n, aber eher vom Ende als vom Anfang zu zählen?
Charlie Harding

14

Sie können auch Argumente von jedem Befehl in Ihrem Verlauf erhalten!


$ 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

Getestet unter Ubuntu 18.04


So fügen Sie vorherige Argumente ein:

  • Alt+ .: Letztes Argument aus dem letzten Befehl einfügen.
  • Alt+ #+ .: füge #nth letztes Argument aus dem letzten Befehl ein.
  • Alt+ -, #, Alt+ ., Zsh: Alt + -+ #+ .: Insert #nth erstes Argument von den letzten Befehl.

Unter Linux können Sie Befehle wiederholen, um in den Verlauf zurückzukehren

Beispiel:

Letzter Befehl ist:

mv foo bar
  • Alt+ 0+ .: erstes Argument des letzten Befehls einfügen =mv
  • Alt+ 2+ .: letztes 2. Argument des letzten Befehls einfügen =foo
  • up, Ctrl+ w: letzter Befehl ohne das letzte Wort =mv foo

Allgemeine Verknüpfungen

  • Ctrl+ w: Entfernt das letzte Wort vom Cursor
  • Alt+ d: Entfernt das nächste Wort vom Cursor
  • Ctrl+ k: schneidet alles nach dem Cursor
  • Ctrl+ u, zsh: Alt + w: schneidet alles vor dem Cursor
  • zsh: Ctrl + u: schneidet den gesamten Befehl ab (In bash können Sie Ctrl+ u, Ctrl+ kombinieren k)
  • Ctrl+ y: Fügen Sie zuvor mit Ctrl+ uund Ctrl+ ausgeschnittene Zeichen eink
  • Ctrl+ _: Letzte Bearbeitung rückgängig machen (sehr nützlich, wenn Ctrl+ überschritten wird w)
  • Ctrl+ left: zum letzten Wort wechseln
  • Ctrl+ right: gehe zum nächsten Wort
  • homeoder Ctrl+ a: zum Zeilenanfang gehen
  • endoder Ctrl+ e: zum Zeilenende gehen

Durchlaufen der Argumente in einem vorherigen Befehl

funktioniert nur in zsh

Führen Sie dies aus oder fügen Sie es Ihrem hinzu ~/.zshrc

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

Verwenden Sie nun Alt+ ., um so zurück zu gehen, wie Sie möchten, und verwenden Sie dann Alt+ :, um die Argumente zu durchlaufen

Vorausgesetzt, der letzte Befehl ist

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

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

Um alle verfügbaren Verknüpfungen anzuzeigen

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

Ich halte dies in dieser Übersicht https://gist.github.com/madacol/da38e42d7e45c2949a9f425cc20543e9 auf dem neuesten Stand


1
Alt .auf Zsh auf Mac tippt 🤔
André Pena

1
Esc . funktioniert, obwohl es nur für den letzten funktioniert. Sie können nicht weiter tippen, um in die Vergangenheit zu reisen. Vielleicht lohnt es sich, die Antwort zu aktualisieren. Vielen Dank.
André Pena

Sie können bindkey -Lin zsh ausgeführt werden, um zu sehen, ob alle Verknüpfungen gebunden sind. Vielleicht hilft dies dabei, das Problem zu lokalisieren oder sogar andere nützliche Befehle zu finden. In meinem Fall zum Beispiel: Die Bindung Alt .ist definiert als bindkey "^[." insert-last-word. Ctrl L(um den Bildschirm zu löschen) -> bindkey "^L" clear-screen. Alt+Ctrl h-> bindkey "^[^H" backward-kill-word(wie Ctrl wum das letzte Wort zu entfernen)
Madacol

@ Madacol Ich kann auch auf Bindeschlüsseln das erwähnte Kopie-früher-Wort als bindkey "^[^_" copy-prev-word
kikeenrique

3

Grundsätzlich hat es eine Verwendung beim Ziehen früherer (Befehls-) Argumente .

Zum Beispiel, wenn der folgende Befehl ausgegeben wird:

echo Hello, world how are you today?

dann Hello,wird das erste Argument sein, und today?das sechste , das ist das letzte; Das heißt, es kann durch Eingabe von: referenziert werden.

Alt+6 gefolgt von Ctrl-Alt-6


Ctrlwird traditionell als Hut Charakter bezeichnet ^vorangestellt Schlüssel Namen, und Altwie M-das heißt M eta - Präfix.

So kann die obige Verknüpfung neu definiert werden, um ^Myzu ziehen.


Außerdem gibt es in der Befehlszeile eine Verknüpfung zum Ersetzen von Hüten :

echo Hello, world!

^Hello^Bye

Bye, world!

um die erste übereinstimmende Zeichenfolge des vorherigen Befehls zu ersetzen , was bedeutet:

Hello, world! Hello, people!

^Hello^Bye

würde führen zu:

Bye, world! Hello, people!

Lassen Sie das zweite Match ( hello) unverändert.

Hinweis: Lassen Sie keinen Platz zwischen den Hüten , da sonst die Operation nicht funktioniert.


Das Obige ist nur eine Abkürzung für:

!:s/Hello/Bye

Die Ersetzung der ersten gefundenen (übereinstimmenden) Zeichenfolge im vorherigen Befehl auf Ereignisebene (*), während das Präfixieren des ersten Teils mit dem gSchalter für die gesamte Zeile g gilt :

echo Hello, world! Hello, people!

!:gs/Hello/Bye

Bye, world! Bye, people!

wie sie üblicherweise in anderen verwandten Befehlen durchgeführt, wie wird sed, viund in regex(regular expression) - einen standart Weg (suchen Matchstring ).

Nein, das kannst du nicht !:sg/Hello/Byeoder !:s/Hello/Bye/ghier, das ist die Syntax !


  • ! ist für Ereignisse; Ereignis kann als Befehlsausgabe oder Operation im Befehlsverlauf verstanden werden.

Das habe ich verstanden, indem ich es selbst verwendet und Dinge selbst ausprobiert habe, die ich aus verschiedenen Quellen gelesen habe, einschließlich Handbuchseiten, Blogs und Foren.

Ich hoffe, es gibt Aufschluss über mysteriöse Möglichkeiten bashder Bourne-Again-Shell (ein Spiel mit der shShell, die nach dem Nachnamen des Erfinders selbst als Bourne-Shell bezeichnet wird), der Standard-Shell in vielen Distributionen, einschließlich Servern ( Server-Betriebssystemen ).


3

! ^ bringt dir den ersten Parameter ,! $ holt dir den letzten Parameter,!: n bringt dir das n-te Element.


0

Die am Ende der akzeptierten Antwort beschriebene Methode funktioniert für mich auch mit dem nullten Argument. Ich habe diese Zeilen in meinem ~/.inputrc:

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

\e2\e.hat den Vorteil, \e2\e\C-ydass vorherige Befehle durchlaufen werden, wenn sie wiederholt gedrückt werden, anstatt das zweite Argument des vorherigen Befehls mehrmals einzufügen.

Um den gesamten vorherigen Befehl einzufügen, können Sie Folgendes eingeben !!\e^. \e^ist history-expand-line.


0

Wenn Sie auf einem Mac arbeiten, erhalten Sie in der Regel erweiterte Zeichen mit Strg + Buchstabe. Ich habe meinen Optionsschlüssel für die Leertaste in meinem Terminal (iTerm2) als Meta definiert. Dies bedeutet, dass ich die Taste verwende, um nach Wörtern zu navigieren und Parameter aus vorherigen Befehlen abzurufen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.