Usando bash history para obtener un comando anterior, cópielo y luego 'ejecútelo' pero con el comando comentado

79

Solo una pregunta para mejorar mis bashhabilidades. Siempre hago esto:

$ history | grep some_long_command

...
...
123 some_long_command1.........
124 some_long_command2.........
...

Luego puedo ejecutar el comando que encontré haciendo:

!123

Sin embargo, a menudo quiero hacer esto:

some_long_command1foobar

Es decir, cambie el comando antes de ejecutarlo. ¿Puedes usar bash para ejecutar este comando en su lugar?

#some_long_command1

por lo que se comenta.

Entonces no tengo que usar mi mouse para resaltar el comando, editarlo y luego ejecutarlo (puedo usar el teclado, más rápido).

Supongo que podría escribir un script para hacerlo, pero es posible que ya haya una funcionalidad incorporada en alguna parte ...

cerveza inglesa
fuente
6
La forma más fácil: bind Space:magic-spaceingrese su perfil de bash. Luego, presionar Spacese expandirá !123a some_long_command1.
Blaz
@cortés: ¡Gracias! Ese era nuevo para mí. Muy útil.
marlar

Respuestas:

140

Sugeriría que en lugar de usar el comando de historial, use ctrl+ry comience a escribir ese comando. Cuando presiona una tecla de flecha como si fuera a modificarla, saldrá del reconocimiento de autocompletar y le permitirá editar antes de ejecutar.

ACTUALIZAR: también, si desea recorrer los diferentes comandos que contienen la cadena que acaba de escribir, siga presionando ctrl+r

Miquel
fuente
8
Si usa combinaciones de teclas vi ( set -o vi), también puede usarlas /para buscar en el historial y editarlo.
William Pursell
1
Una característica más poderosa es permitir escribir un comando parcial o parte de una ruta que estaba en un comando y luego usar las flechas para navegar por el historial. Búsqueda de opciones de búsqueda de historial hacia atrás, búsqueda de historial hacia adelante para bash
DavidC
2
DavidC, he visto a otros hacer esto, pero no me funciona. Cuando escribo las primeras letras de un comando, luego presiono la flecha hacia arriba, ignora lo que estaba escribiendo y pasa por el historial como si no hubiera escrito nada en absoluto (del más nuevo al más antiguo). ¿Cómo configura su shell para lograr esto?
Daniel Watrous
1
Es triste que arriba / abajo no se desplace por las coincidencias, sino que salga inmediatamente de la búsqueda. Hubiera preferido que se desplazara por las coincidencias con arriba / abajo (lo que indica que todavía estoy buscando el comando que quiero), y solo tengo la salida izquierda / derecha de la búsqueda (lo que indica que he encontrado el comando que quiero y ahora estoy listo para editarlo).
ADTC
3
@ADTC Acabo de descubrir una manera de hacer lo que tú (y yo) queremos: presiona ctr+r, comienza a escribir, luego, cuando quieras encontrar todos los comandos que contienen eso, simplemente sigue presionando ctrl+r. En otras palabras, lo que quieres hacer con arriba / abajo se hace (en forma de round robin) conctrl+r
Miquel
61

En realidad, puede agregar :pel comando para imprimirlo sin ejecutarlo. Por ejemplo:

$ ls -la
$ !!:p

Se imprimirá ls -lacomo el comando anterior sin ejecutarlo, y puede presionar (arriba) para encontrarlo y editarlo.

Tu tambien puedes hacer

!123:p

para imprimir el comando 123 como su comando anterior.

joeschmidt45
fuente
2
1 La mejor respuesta, ya que permite a los comandos habituales de historia para responder a la OP: !mycmd:p. Si tiene los comandos vi activados en Bash, la respuesta de Pursell es igual de buena o mejor. Ctrl-r, como lo menciona Miquel, es la siguiente mejor opción.
Brent Faust
Si el 123 no está al comienzo de la línea, puede hacer:!? 123?: P
Udi
19

También puedes probar fc comando para editar el comando en el historial.

WIKI dice,

fc es un programa estándar de Unix que las listas o ediciones y reexecutes, los comandos introducidos previamente a un shell interactivo. fc es un comando integrado en el shell bash ; help fc mostrará información de uso.


Además de la búsqueda incremental inversa ( Ctrl+ R), tenemos algunos atajos de bash más :

De man bash:

historia previa (Cp)
    Obtenga el comando anterior de la lista del historial, retrocediendo en la lista. 
siguiente historia (Cn)
    Obtenga el siguiente comando de la lista del historial, avanzando en la lista. 
comienzo de la historia (M- <)
    Vaya a la primera línea del historial. 
fin de la historia (M->)
    Ir al final del historial de entrada, es decir, la línea que se está ingresando actualmente. 
historial de búsqueda inversa (Cr)
    Busque hacia atrás comenzando en la línea actual y avanzando 'hacia arriba' a través del historial según sea necesario. Esta es una búsqueda incremental.
historial de búsqueda hacia adelante (Cs)
    Busque hacia adelante comenzando en la línea actual y moviéndose 'hacia abajo' a través del historial según sea necesario. Esta es una búsqueda incremental.
historial de búsqueda inversa no incremental (Mp)
    Busque hacia atrás en el historial comenzando en la línea actual utilizando una búsqueda no incremental de una cadena proporcionada por el usuario. 
historial de búsqueda hacia adelante no incremental (Mn)
    Busque hacia adelante en el historial utilizando una búsqueda no incremental de una cadena proporcionada por el usuario.
yank-n-ésimo-arg (MCy)
    Inserte el primer argumento en el comando anterior (generalmente la segunda palabra en la línea anterior) en el punto. Con un argumento n, inserte la enésima palabra del comando anterior (las palabras del comando anterior comienzan con la palabra 0). Un argumento negativo inserta la enésima palabra desde el final del comando anterior. Una vez que se calcula el argumento n, el argumento se extrae como si se hubiera especificado la expansión del historial "! N".
yank-last-arg (M-., M-_)
    Inserte el último argumento del comando anterior (la última palabra de la entrada del historial anterior). Con un argumento, se comporta exactamente como yank-nth-arg. Las sucesivas llamadas a yank-last-arg retroceden por la lista del historial, insertando el último argumento de cada línea por turno. Las facilidades de expansión del historial se utilizan para extraer el último argumento, como si se hubiera especificado la expansión del historial "! $".
shell-expand-line (MCe)
    Expande la línea como lo hace el caparazón. Esto realiza la expansión de alias e historial, así como todas las expansiones de palabras de shell. Consulte EXPANSIÓN DE HISTORIA a continuación para obtener una descripción de la expansión de historia.
historia-expand-línea (M- ^)
    Realice la expansión del historial en la línea actual. Consulte EXPANSIÓN DE HISTORIA a continuación para obtener una descripción de la expansión de historia.
insertar-último-argumento (M-., M-_)
    Un sinónimo de yank-last-arg. 
operar-y-obtener-siguiente (Co)
    Acepte la línea actual para su ejecución y obtenga la siguiente línea relativa a la línea actual del historial para editarla. Se ignora cualquier argumento.
comando-editar-y-ejecutar (C-xC-e)
    Invoque un editor en la línea de comandos actual y ejecute el resultado como comandos de shell.
Príncipe Juan Wesley
fuente
11
!123:gs/old/new/

Ejecutará el comando 123 reemplazando la cadena 'antigua' con la cadena 'nueva'.

John Lawrence
fuente
6

Puede acceder al modo de edición presionando M- ^ (opción-shift-6 en una mac).

Escribe esto:

! 123M- ^

Y estará editando el comando # 123. Es como usar ctrl-r, pero comenzando con la sintaxis del signo de exclamación.

James Moore
fuente
¿Se M-^puede volver a unir a algo más amigable para los dedos?
Blaz
4

En lugar de usar el historycomando, vincule history-search-backward/ history-search-forwarda los atajos de teclado que se pueden recordar fácilmente (prefiero PgUp / PgDown). Para hacer eso, ponga esto en su .inputrcarchivo:

"<key code>":  history-search-backward
"<key code>":  history-search-forward

Para obtener <key code>, escriba Ctrl-V <key>el shell y reemplace el inicio ^[con\e lo que se generó.

Una vez configurado, puede escribir somey presionar RePág para obtener some_long_command. Si lo necesita, some_long_command with_some_argpero hay un comando similar some_long_command with_some_other_argmás adelante en el historial, puede recorrer hasta que lo alcance escribiendo somey luego somepresionando Re Pág repetidamente, o puede escribir , presione Re Pág, mueva el cursor hacia donde los dos comandos comienzan a diferir, escriba algunos caracteres y presione PgUp una vez más. Esta capacidad de paginar rápidamente / diferenciar entre comandos similares la convierte, en mi opinión, en una herramienta mucho más cómoda que Ctrl-R.

Tgr
fuente
3

También puedes poner

shopt -s histverify

en su .bash_profile, lo que hace que cualquier expansión del historial aparezca en su línea de comando sin ejecutarlo, lo que le permite editar antes de hacerlo.

chepner
fuente
1

Puede probar el "cuadro de sugerencias", como el historial https://github.com/dvorka/hstr , lee el historial de Bash y permite una navegación rápida.

S.S

Para obtener el último comando, simplemente escriba hh, navegue hasta el comando y use la flecha derecha para obtenerlo en la línea de comando (donde puede editarlo y / o agregar un comentario).

Martin Dvorak
fuente
0

^ p para obtener el último comando escrito en unix / solaris

SudhakarM
fuente
0

Poner

alias r = 'fc -s'

en su .bashrc(directorio de inicio) entonces puede escribir

r <whatever>

en el símbolo del sistema y ejecutará una copia del último <whatever>comando (los mismos parámetros) que está en su historial. simplemente presione la flecha hacia arriba para ver lo que ha ejecutado si siente la necesidad.

arrojar
fuente