Jak używać argumentów z poprzedniego polecenia?

287

Wiem, że Esc+ .daje ci ostatni argument ostatniego polecenia.

Ale interesuje mnie pierwszy argument ostatniego polecenia. Czy istnieje jakiś wiążący klucz?

Na tej samej linii, czy istnieje ogólny sposób na uzyskanie n-tego argumentu z ostatniego polecenia? Wiem, że w skrypcie bash, można użyć $0, $1itd., Ale to nie działa w wierszu poleceń.

A co z iteracją po zerowym argumencie poprzednich poleceń, tak jak w przypadku ostatniego argumentu przez ciągłe naciskanie Esc+ .?

Aman Jain
źródło

Odpowiedzi:

284

Podobnie jak M-.(meta-kropka, esc-kropka lub alt-kropka) jest funkcją readline yank-last-arg, M-C-y(meta-control-y lub esc-ctrl-y lub ctrl-alt-y) jest funkcją readline yank-nth-arg. Bez określenia n, szarpnie pierwszy argument poprzedniego polecenia.

Aby określić argument, naciśnij klawisz Escape i liczbę lub przytrzymaj klawisz Alt i naciśnij liczbę. Możesz to zrobić Alt- -aby rozpocząć określanie liczby ujemnej, zwolnij klawisz Alt i naciśnij cyfrę (będzie liczona od końca listy argumentów.

Przykład:

Wpisz następujące polecenie

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

Teraz w następnym wierszu wpisz echo(z następującą spacją), a następnie

Naciśnij Alt- Ctrl- ya zobaczysz:

$ echo a

bez naciskania Enterjeszcze wykonaj następujące czynności

Naciśnij Alt- 3 Alt- Ctrl-y

Naciśnij Alt- - 2 Alt- Ctrl-y

Teraz zobaczysz:

$ echo ace

Nawiasem mówiąc, mógłbyś wstawić echowiersz, wybierając argument 0:

Naciśnij Alt- 0 Alt- Ctrl-y

Edytować:

Aby odpowiedzieć na pytanie dodane do oryginału:

Możesz nacisnąć Alt- 0a następnie kilkakrotnie nacisnąć Alt-, .aby przejść przez poprzednie polecenia (arg 0). Podobnie Alt- -następnie powtarzanie Alt- .pozwoliłoby ci przejść przez poprzednie argumenty przedostatnie.

Jeśli nie ma odpowiedniego argumentu na konkretnej linii w historii, dzwonek zadzwoni.

Jeśli często używasz określonej kombinacji, możesz zdefiniować makro, aby wykonać je jednym naciśnięciem klawisza. Ten przykład przywoła drugi argument z poprzednich poleceń, naciskając Alt- Shift- Y. Zamiast tego możesz wybrać dowolne dostępne naciśnięcie klawisza. Możesz naciskać go kilkakrotnie, aby przejść przez poprzednie.

Aby to wypróbować, wprowadź makro po znaku zachęty Bash:

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

Aby było trwałe, dodaj ten wiersz do ~/.inputrcpliku:

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

Niestety wydaje się, że to nie działa w przypadku argumentów 0 lub ujemnych liczb argumentów.

Wstrzymano do odwołania.
źródło
14
Kiedy szukam skrótów klawiaturowych dla bash / readline, lubię biegać bind -lpi patrzeć na bieżące wiązania.
Chad Skeeters
1
@ChadSkeeters: I -s(nowość w Bash 4) wyświetla makra utworzone za pomocą -x.
Wstrzymano do odwołania.
Zauważ, że możesz również użyć argumentu cyfry M-.: Alt-3 Alt-Ctrl-yna przykład oznacza trzymanie Alti pisanie 3.. Jeśli wpiszesz 3.to wiele razy bez zwalniania Alt, przejdziesz do trzeciego argumentu poprzednich linii poleceń.
deser
@dessert: Mówię tyle samo w drugim akapicie, a następnie pokazuję przykład.
Wstrzymano do odwołania.
@ChadSkeeters, dziękuję za ostrzeżenie, że będą setki wpisów! Lol.
jdk1.0
309

!$ pobiera ostatni element poprzedniego argumentu wiersza poleceń.

użytkownik1953081
źródło
115
!:3dostaje trzeci
Matt Dodge
108
! * dostaje was wszystkich
wonton
75
!!dostaje całe ostatnie polecenie. Przydatne, jeśli zapomniałeś użyć sudo.
Un3qual
43
!:1-2dostajesz wszystkie oprócz ostatniego z 3 argumentów
Tyler Brock
5
Tylko słowo ostrzeżenia - jeśli użyjesz połączonych argumentów, np echo foo{,bar} baz. Polecenie zostanie zapisane jako wydrukowane, a następnie rozszerzone. W związku z powyższym użycie echo !:1po rozwiązuje do, echo foo{,bar}a następnie rozwija się doecho foo foobar
Sean
201

Aby użyć pierwszego argumentu, możesz użyć !^lub!:1

Przykład:

$ 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

Ponieważ twoje pytanie dotyczy użycia innych argumentów, oto kilka przydatnych:

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

Pierwsze cztery formy są częściej używane. Forma !:2-jest nieco sprzeczna z intuicją, ponieważ nie zawiera ostatniego argumentu.

niepolarność
źródło
Czy istnieje sposób na zdobycie przedostatniego przedmiotu? tj. dostać file3z mv file1 file2 file3 target/?
Charlie Harding
3
Bardzo podobała mi się ta odpowiedź i ze względu na kompletność proponuję również dodać wiersz informujący o składni „! -2”, który umożliwia dostęp do poprzedniej komendy.
bbv
1
@bbv Dla jeszcze większej kompletności polecenie „! 2”, które pozwala uzyskać dostęp do drugiego wpisu w historii (jeśli nadal jest dostępny w zależności od ustawień historii). Przydatne, jeśli wyświetlasz numer historii w każdym monicie.
816-8055,
53

Tak bardzo podobała mi się odpowiedź @larsmans, że musiałem dowiedzieć się więcej. Dodanie tej odpowiedzi, aby inni mogli znaleźć sekcję strony podręcznika i dowiedzieć się, po co szukać w 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.
Ajith Antony
źródło
18

! ^ może być poleceniem pierwszego argumentu. nie jestem pewien, czy istnieje sposób na uzyskanie n-tego.

Orbita
źródło
7
jest!: n jak zasugerowano powyżej
Sergiu
Czy istnieje sposób na zdobycie n-tego ostatniego przedmiotu, tak !:n, ale licząc od końca niż od początku?
Charlie Harding
14

Możesz także uzyskać argumenty z dowolnego polecenia w historii!


$ 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

GuyMatz
źródło
4

Testowane na Ubuntu 18.04


Aby wstawić poprzednie argumenty:

  • Alt+ .: wstaw ostatni argument z ostatniego polecenia.
  • Alt+ #+ .: wstaw #nth ostatni argument z ostatniego polecenia.
  • Alt+ -, #, Alt+ ., Zsh: Alt + -+# + .: wkładka #nth pierwszy argument z ostatniego polecenia.

W systemie Linux możesz powtarzać polecenia, aby wrócić do historii

Przykład:

Ostatnie polecenie to:

mv foo bar
  • Alt+ 0+ .: wstaw pierwszy argument ostatniego polecenia =mv
  • Alt+ 2+ .: wstaw ostatni 2. argument ostatniego polecenia =foo
  • up, Ctrl+ w: ostatnie polecenie bez ostatniego słowa =mv foo

Skróty ogólne

  • Ctrl+w : usuwa ostatnie słowo z kursora
  • Alt+d : usuwa następne słowo z kursora
  • Ctrl+k : wycina wszystko po kursorze
  • Ctrl+ u, zsh: Alt +w : wycina wszystko przed kursorem
  • zsh: Ctrl + u: wycina całe polecenie (w bash możesz łączyć Ctrl+ u, Ctrl+ k)
  • Ctrl+ y: wklej znaki uprzednio wycięte za pomocą Ctrl+ ui Ctrl+k
  • Ctrl+ _: cofnij ostatnią edycję (bardzo przydatne, gdy przekroczysz Ctrl+ w)
  • Ctrl+ left: przejście do ostatniego słowa
  • Ctrl+ right: przejście do następnego słowa
  • homelub Ctrl+ a: przejście do początku linii
  • endlub Ctrl+ e: przejście do końca linii

Aby iterować argumenty w poprzednim poleceniu

działa tylko w Zsh

uruchom lub dodaj to do swojego ~/.zshrc

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

Teraz użyj Alt+, .aby cofnąć się tak, jak chcesz, a następnie użyj Alt+: aby iterować argumenty

Zakładając, że ostatnim poleceniem jest

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

źródło: https://stackoverflow.com/a/34861762/3163120

Aby zobaczyć wszystkie dostępne skróty

  • grzmotnąć: bind -lp
  • zsh: bindkey -L

Chcę to aktualizować w tym artykule https://gist.github.com/madacol/da38e42d7e45c2949a9f425cc20543e9

Madacol
źródło
1
Alt .na Zsh na Macu pisze 🤔
André Pena
1
Wyjście . działa, chociaż działa tylko dla ostatniego. Nie możesz pisać dalej, by cofnąć się w czasie. Może warto zaktualizować odpowiedź. Dziękuję Ci bardzo.
André Pena
Możesz uruchomić bindkey -Lw Zsh, aby zobaczyć wszystkie skróty powiązane, być może pomoże to zlokalizować problem, a nawet znajdzie inne przydatne polecenia. W moim przypadku na przykład: powiązanie Alt .jest zdefiniowane jako bindkey "^[." insert-last-word. Ctrl L(aby wyczyścić ekran) -> bindkey "^L" clear-screen. Alt+Ctrl h-> bindkey "^[^H" backward-kill-word(tak, jak Ctrl wusunąć ostatnie słowo)
Madacol
@Madacol Widzę również na kluczach powiązania wspomniane słowo kopiowania wcześniejszego jako bindkey "^[^_" copy-prev-word
kikeenrique
3

Zasadniczo ma zastosowanie w szarpaniu poprzednich argumentów (komend) .

Na przykład, jeśli wydane zostanie następujące polecenie:

echo Hello, world how are you today?

Następnie Hello,będzie pierwszy argument, a today?ten szósty , czyli ostatni; co oznacza, że ​​można się do niego odwołać, wpisując:

Alt+6 śledzony przez Ctrl-Alt-6


Ctrljest tradycyjnie oznaczany jako znak kapelusza ^poprzedzony nazwami klawiszy, i Altponieważ M-jest to przedrostek M eta .

Tak więc powyższy skrót można zdefiniować na nowo ^My.


Ponadto w wierszu poleceń znajduje się skrót do zastępowania kapeluszy :

echo Hello, world!

^Hello^Bye

Bye, world!

podstawić pierwszy dopasowany ciąg poprzedniego polecenia , co oznacza:

Hello, world! Hello, people!

^Hello^Bye

spowodowałoby:

Bye, world! Hello, people!

pozostawiając drugi match ( hello) bez zmian.

Uwaga: nie zostawiaj miejsca między czapkami , bo operacja nie zadziała.


Powyższe to tylko skrót do:

!:s/Hello/Bye

podstawienie na poziomie zdarzenia (*) dla pierwszego znalezionego (dopasowanego) ciągu w poprzednim poleceniu, podczas gdy prefiksowanie pierwszej części gprzełącznikiem będzie miało zastosowanie do całej linii g lokalnie :

echo Hello, world! Hello, people!

!:gs/Hello/Bye

Bye, world! Bye, people!

jak zwykle dzieje się to w innych pokrewnych poleceniach, takich jak sed, vii regex(wyrażenie regularne) - standardowy sposób wyszukiwania ( dopasowanie łańcucha ).

Nie, nie możesz zrobić !:sg/Hello/Byeani !:s/Hello/Bye/gtutaj, taka jest składnia !


  • ! jest na imprezy; zdarzenie może być rozumiane jako wynik polecenia lub operacja wykonana w historii poleceń.

Właśnie to zrozumiałem, używając go sam i próbując samodzielnie z tego, co czytam z różnych źródeł, w tym stron podręczników, blogów i forów.

Mam nadzieję, że rzuci nieco światła na tajemnicze sposoby bash, powłoki Bourne-Again (gra na shpowłoce, która sama nazywa się powłoką Bourne'a po nazwisku wynalazcy), która jest domyślną powłoką w wielu dystrybucjach, w tym serwerach ( systemach operacyjnych serwera ).


źródło
3

! ^ dostanie pierwszy parametr,! $ dostanie ostatni parametr,!: n dostanie n-ty element.

Moshe Bixenshpaner
źródło
0

Metoda opisana na końcu zaakceptowanej odpowiedzi działa również dla mnie z zerowym argumentem. Mam te linie w moim ~/.inputrc:

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

\e2\e.ma tę przewagę \e2\e\C-y, że cyklicznie przechodzi przez poprzednie polecenia, jeśli jest naciskany wielokrotnie zamiast wielokrotnie wstawiać drugi argument poprzedniego polecenia.

Aby wstawić całe poprzednie polecenie, możesz wpisać !!\e^. \e^jest history-expand-line.

nisetama
źródło
0

Jeśli używasz komputera Mac, będziesz miał tendencję do uzyskiwania rozszerzonych znaków za pomocą klawiszy Ctrl + litera. Mam skonfigurowany mój klawisz opcji spacji-spacji zdefiniowany jako meta w moim terminalu (iTerm2). Oznacza to, że używam klawisza do nawigacji po słowie i pobierania parametrów z poprzednich poleceń.

Colin
źródło