Come usare gli argomenti del comando precedente?


288

So che Esc+ .ti dà l'ultimo argomento dell'ultimo comando.

Ma sono interessato al primo argomento dell'ultimo comando. Esiste un legame chiave per farlo?

Sulla stessa linea, esiste un modo generico per ottenere l'ennesimo argomento dall'ultimo comando? So che in uno script bash, puoi usare $0, $1ecc., Ma questi non funzionano sulla riga di comando.

Inoltre, per quanto riguarda l'iterazione attraverso l'argomento 0 dei comandi precedenti, come possiamo fare con l'ultimo argomento premendo continuamente Esc+ .?

Risposte:


284

Proprio come M-.(meta-punto o esc-punto o alt-punto) è la funzione readline yank-last-arg, M-C-y(meta-controllo-y o esc-ctrl-y o ctrl-alt-y) è la funzione readline yank-nth-arg. Senza specificare n, strappa il primo argomento del comando precedente.

Per specificare un argomento, premi Esc e un numero o tieni premuto Alt e premi un numero. Puoi fare Alt- -per iniziare a specificare un numero negativo, quindi rilascia Alt e premi il numero (questo conterà dalla fine dell'elenco degli argomenti.

Esempio:

Immettere il comando seguente

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

Ora al prossimo prompt, digitare echo(con uno spazio seguente), quindi

Premi Alt- Ctrl- ye ora vedrai:

$ echo a

senza premere Enterancora, procedi come segue

Premere Alt- 3 Alt- Ctrl-y

Premere Alt- - 2 Alt- Ctrl-y

Ora vedrai:

$ echo ace

A proposito, avresti potuto mettere echoin riga selezionando l'argomento 0:

Premere Alt- 0 Alt- Ctrl-y

Modificare:

Per rispondere alla domanda che hai aggiunto al tuo originale:

È possibile premere Alt- 0quindi premere più volte Alt- .per scorrere i comandi precedenti (arg 0). Allo stesso modo Alt, -quindi ripetendo Alt, .ti permetterebbe di passare attraverso gli argomenti penultimo.

Se non ci sono argomenti appropriati su una determinata linea della storia, la campana verrà suonata.

Se c'è una combinazione particolare che usi frequentemente, puoi definire una macro in modo che una sequenza di tasti la esegua. In questo esempio verrà richiamato il secondo argomento dai comandi precedenti premendo Alt- Shift- Y. Puoi scegliere qualsiasi tasto disponibile che preferisci invece di questo. Puoi premerlo più volte per scorrere tra quelli precedenti.

Per provarlo, inserisci la macro al prompt di Bash:

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

Per renderlo persistente, aggiungi questa riga al tuo ~/.inputrcfile:

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

Sfortunatamente, questo non sembra funzionare con arg 0 o numeri di argomento negativi.


14
Quando cerco scorciatoie da tastiera per bash / readline, mi piace correre bind -lpe guardare le associazioni correnti.
Chad Skeeters,

1
@ChadSkeeters: E -s(novità in Bash 4) elenca le macro create usando -x.
In pausa fino a nuovo avviso.

Nota che puoi usare anche l'argomento digit con M-.: Alt-3 Alt-Ctrl-yper esempio equivale a trattenere Alte digitare 3.. Se lo digiti 3.più volte senza rilasciarlo Alt, passa attraverso i terzi argomenti delle precedenti righe di comando.
dessert,

@dessert: dico altrettanto nel mio secondo paragrafo e poi mostro un esempio.
In pausa fino a nuovo avviso.

@ChadSkeeters, grazie per l'avvertimento che ci sarebbero state centinaia di voci! Lol.
jdk1.0,

310

!$ ottiene l'ultimo elemento del precedente argomento della riga di comando.


115
!:3ti procura il terzo
Matt Dodge,

108
! * ti prende tutti
wonton

75
!!ti dà l'intero ultimo comando. Utile se hai dimenticato di usare sudo.
Un3qual

43
!:1-2ti dà tutto tranne l'ultimo di 3 argomenti
Tyler Brock il

5
Solo un avvertimento: se si usano argomenti combinati come echo foo{,bar} baz, il comando viene registrato come stampato e si espande in seguito. Con quanto sopra, usando echo !:1after si risolve echo foo{,bar}e poi si espande inecho foo foobar
Sean

201

Per usare il primo argomento, puoi usare !^o!:1

Esempio:

$ 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

Poiché la tua domanda riguarda l'uso di altri argomenti, eccone alcuni utili:

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

Le prime quattro forme sono più spesso utilizzate. Il modulo !:2-è alquanto intuitivo, in quanto non include l'ultimo argomento.


C'è un modo per ottenere il penultimo elemento? cioè arrivare file3da mv file1 file2 file3 target/?
Charlie Harding,

3
Mi è piaciuta molto questa risposta e solo per completezza, suggerisco di aggiungere anche una riga che parla della sintassi '! -2' che ti consente di accedere al comando precedente al precedente.
bbv,

1
@bbv Anche per maggiore completezza il comando '! 2' che consente di accedere alla seconda voce nella cronologia (se è ancora disponibile a seconda delle impostazioni della cronologia). Utile se si visualizza il numero di cronologia in ogni prompt.
816-8055

53

Mi è piaciuta la risposta di @larsmans così tanto che ho dovuto imparare di più. Aggiungendo questa risposta per aiutare gli altri a trovare la sezione della pagina man e sapere cosa cercare su 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

! ^ potrebbe essere il comando per il primo argomento. non sono sicuro che ci sia un modo per ottenere l'ennesimo.


7
lo è!: n come suggerito sopra
Sergiu,

C'è un modo per ottenere l'ennesimo elemento, in modo simile !:n, ma contando dalla fine piuttosto che dall'inizio?
Charlie Harding,

14

Puoi anche ottenere argomenti da qualsiasi comando della tua cronologia!


$ 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


5

Testato su Ubuntu 18.04


Per inserire argomenti precedenti:

  • Alt+. : inserisce l'ultimo argomento dall'ultimo comando.
  • Alt+ #+ .: inserisci # ennesimo argomento dall'ultimo comando.
  • Alt+ -, #, Alt+ ., Zsh: Alt + -+ #+ .: inserto #nth primo argomento da ultimo comando.

In Linux puoi ripetere i comandi per tornare indietro nella storia

Esempio:

L'ultimo comando è:

mv foo bar
  • Alt+ 0+ .: inserisci il primo argomento dell'ultimo comando =mv
  • Alt+ 2+ .: inserisci l'ultimo secondo argomento dell'ultimo comando =foo
  • up, Ctrl+ w: ultimo comando senza l'ultima parola =mv foo

Scorciatoie generali

  • Ctrl+ w: rimuove l'ultima parola dal cursore
  • Alt+ d: rimuove la parola successiva dal cursore
  • Ctrl+ k: taglia tutto dopo il cursore
  • Ctrl+ u, zsh: Alt + w: taglia tutto prima del cursore
  • zsh: Ctrl + u: taglia l'intero comando (in bash puoi combinare Ctrl+ u, Ctrl+ k)
  • Ctrl+ y: incolla i caratteri precedentemente tagliati con Ctrl+ ue Ctrl+k
  • Ctrl+ _: annulla ultima modifica (molto utile quando si supera Ctrl+ w)
  • Ctrl+ left: passa all'ultima parola
  • Ctrl+ right: passa alla parola successiva
  • homeoppure Ctrl+ a: sposta all'inizio della riga
  • endoppure Ctrl+ e: passa alla fine della riga

Per scorrere gli argomenti in un comando precedente

funziona solo in zsh

esegui o aggiungi questo al tuo ~/.zshrc

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

Ora usa Alt+ .per tornare indietro come vuoi, quindi usa Alt+: per scorrere gli argomenti

Supponendo che l'ultimo comando sia

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

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

Per vedere tutte le scorciatoie disponibili

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

Lo tengo aggiornato in questa sintesi https://gist.github.com/madacol/da38e42d7e45c2949a9f425cc20543e9


1
Alt .su Zsh su Mac sta scrivendo 🤔
André Pena il

1
Esc . funziona, anche se funziona solo per l'ultimo. Non puoi continuare a digitare per tornare indietro nel tempo. Forse varrebbe la pena aggiornare la risposta. Grazie mille.
André Pena,

Potresti eseguire bindkey -Lin zsh per vedere tutti i collegamenti associati, forse aiuterà a individuare il problema o anche a trovare altri comandi utili. Nel mio caso ad esempio: l'associazione Alt .è definita come bindkey "^[." insert-last-word. Ctrl L(per cancellare lo schermo) -> bindkey "^L" clear-screen. Alt+Ctrl h-> bindkey "^[^H" backward-kill-word(come Ctrl wper rimuovere l'ultima parola)
Madacol,

@Madacol Posso anche vedere sui tasti di associazione la menzionata copia-precedente-parola come bindkey "^[^_" copy-prev-word
kikeenrique

3

Fondamentalmente ha un uso nel strappare argomenti precedenti (di comando) .

Ad esempio, se viene emesso il seguente comando:

echo Hello, world how are you today?

poi, Hello,sarà il primo argomento, e today?il sesto , che è l'ultimo; nel senso che può essere referenziato digitando:

Alt+6 seguito da Ctrl-Alt-6


Ctrlè tradizionalmente indicato come un carattere cappello ^anteposto ai nomi delle chiavi, e Altpoiché M-questo è il prefisso M eta .

Quindi la scorciatoia sopra può essere ridefinita per quanto ^Myriguarda lo strappo.


Inoltre, nella riga di comando è presente un collegamento per la sostituzione di cappelli :

echo Hello, world!

^Hello^Bye

Bye, world!

per sostituire la prima stringa corrispondente del comando precedente , ovvero:

Hello, world! Hello, people!

^Hello^Bye

comporterebbe:

Bye, world! Hello, people!

lasciando helloinvariata la seconda partita ( ).

Nota: non lasciare spazio tra i cappelli , altrimenti l'operazione non funzionerà.


Quanto sopra è solo una scorciatoia per:

!:s/Hello/Bye

la sostituzione a livello di evento (*) per la prima stringa trovata (abbinata) nel comando precedente, mentre il prefisso della prima parte con l' ginterruttore si applica all'intera riga g lobalmente :

echo Hello, world! Hello, people!

!:gs/Hello/Bye

Bye, world! Bye, people!

come di solito viene fatto in altri comandi correlati come sed, vie in regex(espressione regolare) - un modo standard per la ricerca ( stringa di corrispondenza ).

No, non puoi farlo !:sg/Hello/Byeo !:s/Hello/Bye/gqui, questa è la sintassi !


  • ! è per eventi; L'evento potrebbe essere inteso come output del comando o operazione eseguita nella cronologia dei comandi.

Questo è quello che ho capito usandolo da solo e provando le cose da solo da ciò che ho letto da varie fonti tra cui pagine di manuale, blog e forum.

Spero che faccia luce su modi misteriosi di bash, la shell Bourne-Again (un gioco sulla shshell, che a sua volta si chiama Bourne shell dopo il cognome del suo inventore), qual è la shell predefinita in molte distribuzioni tra cui server ( server OS ).


3

! ^ ti porterà il primo parametro,! $ ti porterà l'ultimo parametro,!: n ti darà l'ennesimo elemento.


0

Il metodo descritto alla fine della risposta accettata funziona anche con l'argomento zeroth per me. Ho queste righe nel mio ~/.inputrc:

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

\e2\e.ha il vantaggio di \e2\e\C-yscorrere ciclicamente i comandi precedenti se viene premuto ripetutamente invece di inserire più volte il secondo argomento del comando precedente.

Per inserire l'intero comando precedente, è possibile digitare !!\e^. \e^lo è history-expand-line.


0

Se sei su un Mac tenderai a ottenere caratteri estesi con ctrl + lettera. Ho il mio tasto di opzione della barra dello spazio di destra definito come meta nel mio terminale (iTerm2) impostato. Questo significa che uso il tasto per navigare per parola ed estrarre i parametri dai comandi precedenti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.