¿Cómo usar argumentos del comando anterior?

287

Sé que Esc+ .te da el último argumento del último comando.

Pero estoy interesado en el primer argumento del último comando. ¿Hay alguna clave vinculante para hacerlo?

En la misma línea, ¿hay una forma genérica de obtener el enésimo argumento del último comando? Sé que en un script bash, puedes usar $0, $1etc., pero estos no funcionan en la línea de comandos.

Además, ¿qué hay de iterar a través del argumento 0 de los comandos anteriores, como podemos hacer con el último argumento presionando continuamente Esc+ .?

Aman Jain
fuente

Respuestas:

284

Así como M-.(meta-dot o esc-dot o alt-dot) es la función readline yank-last-arg, M-C-y(meta-control-y o esc-ctrl-y o ctrl-alt-y) es la función readline yank-nth-arg. Sin especificar n, tira del primer argumento del comando anterior.

Para especificar un argumento, presione Escape y un número o mantenga presionada la tecla Alt y presione un número. Puede hacerlo Alt: -para comenzar a especificar un número negativo, luego suelte Alt y presione el dígito (esto contará desde el final de la lista de argumentos.

Ejemplo:

Ingrese el siguiente comando

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

Ahora en el siguiente indicador, escriba echo(con el siguiente espacio), luego

Prensa Alt- Ctrl- yy ahora verá:

$ echo a

sin presionar Enteraún, haga lo siguiente

Presione Alt- 3 Alt- Ctrl-y

Presione Alt- - 2 Alt- Ctrl-y

Ahora verás:

$ echo ace

Por cierto, podría haber puesto el echoen la línea seleccionando el argumento 0:

Presione Alt- 0 Alt- Ctrl-y

Editar:

Para responder la pregunta que agregó a su original:

Puede presionar Alt, 0luego presionar repetidamente Alt, .para recorrer los comandos anteriores (arg 0). Del mismo modo Alt, -luego repetir Alt, .le permitiría pasar por los anteriores y anteriores argumentos.

Si no hay un argumento apropiado en una línea particular en la historia, se tocará la campana.

Si hay una combinación particular que usa con frecuencia, puede definir una macro para que una pulsación de tecla la realice. Este ejemplo recordará el segundo argumento de los comandos anteriores presionando Alt- Shift- Y. Puede elegir cualquier pulsación de tecla disponible que prefiera en lugar de esta. Puede presionarlo repetidamente para pasar por los anteriores.

Para probarlo, ingrese la macro en un indicador de Bash:

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

Para hacerlo persistente, agregue esta línea a su ~/.inputrcarchivo:

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

Desafortunadamente, esto no parece funcionar para arg 0 o números de argumentos negativos.

Pausado hasta nuevo aviso.
fuente
14
Cuando busco atajos de teclado para bash / readline, me gusta correr bind -lpy mirar los enlaces actuales.
Chad Skeeters
1
@ChadSkeeters: Y -s(nuevo en Bash 4) enumera las macros creadas con -x.
Pausado hasta nuevo aviso.
Tenga en cuenta que también puede usar el argumento dígito M-.: Alt-3 Alt-Ctrl-ypor ejemplo, es igual a mantener Alty escribir 3.. Si escribe 3.eso varias veces sin soltarlo Alt, revise los terceros argumentos de sus líneas de comando anteriores.
postre
@dessert: lo digo en mi segundo párrafo y luego muestro un ejemplo.
Pausado hasta nuevo aviso.
@ChadSkeeters, ¡gracias por la advertencia de que habría cientos de entradas! Jajaja
jdk1.0
309

!$ obtiene el último elemento del argumento anterior de la línea de comando.

usuario1953081
fuente
115
!:3te consigue el tercero
Matt Dodge
108
! * te lleva a todos
wonton
75
!!te da todo el último comando. Útil si olvidó usar sudo.
Un3qual
43
!:1-2te da todo menos el último de 3 argumentos
Tyler Brock
55
Solo una palabra de advertencia: si usa argumentos combinados como echo foo{,bar} baz, el comando se registra como impreso y luego se expande. Con lo anterior, el uso de echo !:1after se resuelve echo foo{,bar}y luego se expande aecho foo foobar
Sean
200

Para usar el primer argumento, puede usar !^o!:1

Ejemplo:

$ 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

Como su pregunta es sobre el uso de cualquier otro argumento, aquí hay algunos útiles:

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

Las primeras cuatro formas se usan con más frecuencia. El formulario !:2-es algo contrario a la intuición, ya que no incluye el último argumento.

nonopolaridad
fuente
¿Hay alguna forma de obtener el penúltimo artículo? es decir, obtener file3de mv file1 file2 file3 target/?
Charlie Harding
3
Me gustó mucho esta respuesta y solo por el bien de la integridad, sugiero agregar también una línea que diga sobre la sintaxis '! -2' que le permite acceder al comando anterior al anterior.
bbv
1
@bbv También para obtener una mayor integridad, el comando '! 2', que le permite acceder a la segunda entrada en el historial (si aún está disponible según la configuración de su historial). Útil si muestra el número del historial en cada solicitud.
816-8055
53

Me gustó tanto la respuesta de @larsmans que tuve que aprender más. Agregar esta respuesta para ayudar a otros a encontrar la sección de la página de manual y saber para qué buscar en 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
fuente
18

! ^ puede ser el comando para el primer argumento. No estoy seguro de si hay una manera de obtener el enésimo.

Orbita
fuente
77
es!: n como se sugirió anteriormente
Sergiu
¿Hay alguna forma de obtener el enésimo último elemento, por ejemplo !:n, pero contando desde el final en lugar del principio?
Charlie Harding
14

¡También puede obtener argumentos de cualquier comando en su historial!


$ 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
fuente
4

Probado en Ubuntu 18.04


Para insertar argumentos anteriores:

  • Alt+. : inserta el último argumento del último comando.
  • Alt+ #+ .: inserta el décimo último argumento del último comando.
  • Alt+ -, #, Alt+ ., Zsh: Alt + -+ #+ .: inserción #nth primer argumento del último comando.

En Linux puedes repetir comandos para volver al historial

Ejemplo:

El último comando es:

mv foo bar
  • Alt+ 0+ .: inserta el primer argumento del último comando =mv
  • Alt+ 2+ .: inserta el último segundo argumento del último comando =foo
  • up, Ctrl+ w: último comando sin la última palabra =mv foo

Atajos generales

  • Ctrl+ w: elimina la última palabra del cursor
  • Alt+ d: elimina la siguiente palabra del cursor
  • Ctrl+ k: corta todo después del cursor
  • Ctrl+ u, zsh: Alt +w : corta todo antes del cursor
  • zsh: Ctrl + u: corta todo el comando (en bash puedes combinar Ctrl+ u, Ctrl+ k)
  • Ctrl+ y: pegar caracteres cortados previamente con Ctrl+ uy Ctrl+k
  • Ctrl+ _: deshacer la última edición (muy útil cuando excede Ctrl+ w)
  • Ctrl+ left: pasar a la última palabra
  • Ctrl+ right: pasar a la siguiente palabra
  • homeo Ctrl+ a: mover al inicio de la línea
  • endo Ctrl+ e: mover al final de la línea

Para iterar a través de los argumentos en un comando anterior

solo funciona en zsh

ejecutar o agregar esto a su ~/.zshrc

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

Ahora use Alt+ .para ir tan atrás como desee, luego use Alt+: para recorrer los argumentos

Asumiendo que el último comando es

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

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

Para ver todos los atajos disponibles

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

Estoy manteniendo esto actualizado en esta esencia https://gist.github.com/madacol/da38e42d7e45c2949a9f425cc20543e9

Madacol
fuente
1
Alt .en Zsh en Mac está escribiendo 🤔
André Pena
1
Esc . funciona, aunque solo funcione para el último. No puedes seguir escribiendo para retroceder en el tiempo. Quizás valga la pena actualizar la respuesta. Muchas gracias.
André Pena
Puede ejecutar bindkey -Len zsh para ver todos los accesos directos vinculados, tal vez ayude a identificar el problema o incluso encontrar otros comandos útiles. En mi caso, por ejemplo: el enlace Alt .se define como bindkey "^[." insert-last-word. Ctrl L(para borrar la pantalla) -> bindkey "^L" clear-screen. Alt+Ctrl h-> bindkey "^[^H" backward-kill-word(igual que Ctrl wpara eliminar la última palabra)
Madacol
@Madacol También puedo ver en las teclas de enlace la mencionada copia de la palabra anterior como bindkey "^[^_" copy-prev-word
kikeenrique
3

Básicamente tiene un uso en arrancar argumentos anteriores (del comando) .

Por ejemplo, si se emite el siguiente comando:

echo Hello, world how are you today?

entonces, Hello,será el primer argumento, y today?el sexto , ese es el último; lo que significa que se puede hacer referencia al escribir:

Alt+6 seguido por Ctrl-Alt-6


Ctrltradicionalmente se denota como un carácter de sombrero ^antepuesto a los nombres de las teclas, y Altcomo M-ese es el prefijo M eta .

Por lo tanto, el acceso directo anterior se puede redefinir ^Mypara tirar.


Además, hay un acceso directo de sustitución de sombreros en la línea de comando:

echo Hello, world!

^Hello^Bye

Bye, world!

para sustituir la primera cadena coincidente del comando anterior , lo que significa:

Hello, world! Hello, people!

^Hello^Bye

daría como resultado:

Bye, world! Hello, people!

dejando el segundo partido ( hello) sin cambios.

Nota: No deje espacio entre sombreros , o la operación no funcionará.


Lo anterior es solo un atajo para:

!:s/Hello/Bye

La sustitución de nivel de evento (*) para la primera cadena encontrada (coincidente) en el comando anterior, mientras que el prefijo de la primera parte con el ginterruptor se aplicará a toda la línea g lobally :

echo Hello, world! Hello, people!

!:gs/Hello/Bye

Bye, world! Bye, people!

como se suele hacer en otros comandos relacionados, como sed, viy en regex(expresión regular), una forma estándar de búsqueda ( cadena de coincidencias ).

No, no puedes hacer !:sg/Hello/Byeo !:s/Hello/Bye/gaquí, ¡esa es la sintaxis !


  • ! es para eventos; evento puede entenderse como salida de comando u operación realizada en el historial de comandos.

Eso es lo que entendí al usarlo yo mismo y probar cosas por mi cuenta a partir de lo que leí de varias fuentes, incluidas páginas de manual, blogs y foros.

Espero que arroje algo de luz sobre formas misteriosas del bashshell Bourne-Again (un juego en shshell, que se llama Bourne shell después del apellido de su inventor), que es el shell predeterminado en muchas distribuciones, incluidos los servidores ( SO de servidor ).


fuente
3

! ^ te dará el primer parámetro,! $ te dará el último parámetro,!: n te dará el enésimo elemento.

Moshe Bixenshpaner
fuente
0

El método descrito al final de la respuesta aceptada también funciona con el argumento cero para mí. Tengo estas líneas en mi ~/.inputrc:

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

\e2\e.tiene la ventaja de \e2\e\C-yque recorre los comandos anteriores si se presiona repetidamente en lugar de insertar el segundo argumento del comando anterior varias veces.

Para insertar todo el comando anterior, puede escribir !!\e^. \e^es history-expand-line.

nisetama
fuente
0

Si está en una Mac, tenderá a obtener caracteres extendidos con Ctrl + letra. Tengo mi clave de opción de barra de espacio derecho definida como meta en mi terminal (iTerm2) configurada. Esto significa que uso la tecla para navegar por palabra y extraer parámetros de comandos anteriores.

colin
fuente