¿Cómo eliminar comandos en el historial que coinciden con una cadena dada?

13

Necesito eliminar todos los comandos en mi historial que coinciden con una cadena. He intentado:

$ history | grep searchstring | cut -d" " -f2 | history -d
-bash: history: -d: option requires an argument

$ history | grep searchstring | cut -d" " -f2 | xargs history -d
xargs: history: No such file or directory

$ temparg() { while read i; do "$@" "$i"; done }
$ history | grep searchstring | cut -d" " -f2 | temparg history -d
(no error, but nothing is deleted)

¿Cuál es la forma correcta de hacer esto?

linuxfix
fuente
Si bien hay respuestas que funcionan a continuación, todavía me pregunto por qué no funciona history -d X. Encontré esta pregunta porque acababa de hacerlo history | grep search_str | sort -nr | awk '{print $1}' | while read i; do history -d $i; done. Sin error, pero nada eliminado. ¿Alguien puede explicar por qué?
mivk

Respuestas:

18

El historycomando solo opera en su archivo de historial, $HISTFILE(típicamente ~/.historyo ~/.bash_history). Será mucho más fácil si solo elimina las líneas de ese archivo, lo que se puede hacer de muchas maneras. grepes una forma, pero debe tener cuidado de no sobrescribir el archivo mientras lo sigue leyendo:

$ grep -v searchstring "$HISTFILE" > /tmp/history
$ mv /tmp/history "$HISTFILE"

Otra forma es con sed:

$ sed -i '/searchstring/d' "$HISTFILE"
Michael Mrozek
fuente
Buena respuesta; $HISTFILEpodría contener espacios, probablemente valga la pena citarlo.
Chris Down
Cuidado ... histfile es impredecible, si tienes muchos proyectiles abiertos, no se sabe exactamente qué se guardará y en qué orden. ¿Alguien puede confirmar que los shells ya abiertos no reescribirán el historial que cargaron en la inicialización, cuando están cerrados?
orion
8

La respuesta de Michael Mrozek funcionará si no te importa eliminar comandos de la sesión actual. Si lo hace, debe escribir en el archivo de historial antes de realizar las operaciones en su publicación haciendo history -a.

Además, después de haber eliminado las entradas que desea de su archivo de historial, puede volver a cargarlo emitiendo history -c, luegohistory -r .

Chris Down
fuente
2

Basado en las respuestas de Michael y Chris , se me ocurrió lo siguiente. Agréguelo a su ~/.bashrcarchivo y luego cárguelo con . ~/.bashrco source ~/.bashrc.

:<<COMMENT
    Deletes all lines from the history that match a search string, with a
    prompt. The history file is then reloaded into memory.

    Examples
        hxf "rm -rf"
        hxf ^source

    See:
    - https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string
COMMENT
#The unalias prevents odd errors when calling". ~/.bashrc" (May result in
#"not found" errors. That's okay).
unalias hxf
hxf()  {
    read -r -p "About to delete all items from history that match \"$1\". Are you sure? [y/N] " response
    response=${response,,}    # tolower
    if [[ $response =~ ^(yes|y)$ ]]
    then
        #Delete all matched items from the file, and duplicate it to a temp
        #location.
        echo -e "grep -v \"$1\" \"$HISTFILE\" > /tmp/history"
        grep -v "$1" "$HISTFILE" > /tmp/history

        #Clear all items in the current sessions history (in memory). This
        #empties out $HISTFILE.
        echo "history -c"
        history -c

        #Overwrite the actual history file with the temp one.
        echo -e "mv /tmp/history \"$HISTFILE\""
        mv /tmp/history "$HISTFILE"

        #Now reload it.
        echo -e "history -r \"$HISTFILE\""
        history -r "$HISTFILE"     #Alternative: exec bash
    else
        echo "Cancelled."
    fi
}
mente mental
fuente
2

Para aquellos que buscan una línea:

while history -d $(history | grep 'SEARCH_STRING_GOES_HERE'| head -n 1 | awk {'print $1'}) ; do :; history -w; done

Entonces, si quisieras, por ejemplo. elimine varias líneas con una contraseña, simplemente reemplace "SEARCH_STRING_GOES_HERE" con la contraseña. Esto buscará en todo tu historial esa cadena de búsqueda y la eliminará.

2 cosas a tener en cuenta

  • grep usa regex a menos que proporcione -F como argumento
  • El comando mostrará 1 error, una vez que no haya más coincidencias. Ignoralo.
thelogix
fuente
Recibí un error (-bash: history: -d: la opción requiere un argumento), pero ¿funcionó?
paradroid
Ejecuta el comando eliminar continuamente, hasta que falla con un error (porque no hay nada más que eliminar). Solo ignora el error.
thelogix
1
cat "$HISTFILE" | grep -v "commandToDelete" >> "$HISTFILE" && exit

Esto funcionó para mí. history -c && history -a no volvió a cargar el archivo de historial correctamente para mí. Entonces, en cambio, salgo de mi sesión justo después de reescribir el archivo de historial para que el que está en la memoria no lo sobrescriba.

Hydde87
fuente