Come eliminare i comandi nella cronologia corrispondenti a una determinata stringa?


13

Devo eliminare tutti i comandi nella mia cronologia che corrispondono a una stringa. Ho provato:

$ 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)

Qual è il modo giusto per farlo?


Mentre ci sono risposte funzionanti di seguito, mi chiedo ancora perché non funziona history -d X. Mi sono imbattuto in questa domanda perché avevo appena fatto history | grep search_str | sort -nr | awk '{print $1}' | while read i; do history -d $i; done. Nessun errore, ma niente eliminato. Qualcuno può spiegare perché?
marzo

Risposte:


18

Il historycomando funziona solo sul file della cronologia, $HISTFILE(in genere ~/.historyo ~/.bash_history). Sarà molto più semplice se rimuovi le righe da quel file, cosa che può essere fatta in molti modi. grepè un modo, ma devi fare attenzione a non sovrascrivere il file mentre lo leggi ancora:

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

Un altro modo è con sed:

$ sed -i '/searchstring/d' "$HISTFILE"

Buona risposta; $HISTFILEpotrebbe contenere spazi, probabilmente vale la pena citarlo.
Chris Down,

Attento ... il file hist è imprevedibile, se hai molte shell aperte, non si può dire cosa verrà salvato esattamente e in quale ordine. Qualcuno può confermare che le shell già aperte non riscriveranno la cronologia caricata all'inizializzazione, quando chiuse?
Orione,

8

La risposta di Michael Mrozek funzionerà se non ti interessa rimuovere i comandi dalla sessione corrente. Se lo fai, dovresti scrivere nel file della cronologia prima di fare le operazioni nel suo post history -a.

Inoltre, dopo aver rimosso le voci desiderate dal file della cronologia, è possibile ricaricarle emettendo history -c, quindi history -r.


2

Sulla base delle risposte di Michael e Chris , ho pensato a quanto segue. Aggiungilo al tuo ~/.bashrcfile e poi caricalo 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
}

2

Per chi cerca un one-liner:

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

Quindi, se volessi es. elimina più righe con una password, sostituisci semplicemente "SEARCH_STRING_GOES_HERE" con la password. Questo cercherà tutta la cronologia per quella stringa di ricerca e la cancellerà.

2 cose da tenere presente

  • grep usa regex a meno che non forniate -F come argomento
  • Il comando mostrerà 1 errore, quando non ci saranno più corrispondenze. Ignoralo.

Ho ricevuto un errore (-bash: history: -d: opzione richiede un argomento), ma ha ancora funzionato?
paradroid

Esegue continuamente il comando delete, fino a quando non fallisce con un errore (perché non c'è altro da eliminare). Ignora l'errore.
thelogix

1
cat "$HISTFILE" | grep -v "commandToDelete" >> "$HISTFILE" && exit

Questo ha funzionato per me. history -c && history -a non ha ricaricato correttamente il file della cronologia. Quindi, invece, esco dalla sessione subito dopo aver riscritto il file cronologico in modo che quello in memoria non lo sovrascriva.

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.