Wie lösche ich Befehle im Verlauf, die einer bestimmten Zeichenfolge entsprechen?

13

Ich muss alle Befehle in meinem Verlauf löschen, die einer Zeichenfolge entsprechen. Ich habe es versucht:

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

Was ist der richtige Weg, um dies zu tun?

linuxfix
quelle
Obwohl es unten funktionierende Antworten gibt, frage ich mich immer noch, warum das nicht funktioniert history -d X. Ich bin auf diese Frage gestoßen, weil ich es gerade getan hatte history | grep search_str | sort -nr | awk '{print $1}' | while read i; do history -d $i; done. Kein Fehler, aber nichts gelöscht. Kann jemand erklären, warum?
Mivk

Antworten:

17

Der historyBefehl wird nur für Ihre Verlaufsdatei ausgeführt $HISTFILE(normalerweise ~/.historyoder ~/.bash_history). Es ist viel einfacher, wenn Sie einfach die Zeilen aus dieser Datei entfernen, was auf viele Arten möglich ist. grepDies ist eine Möglichkeit, aber Sie müssen darauf achten, die Datei nicht zu überschreiben, während Sie sie noch lesen:

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

Ein anderer Weg ist mit sed:

$ sed -i '/searchstring/d' "$HISTFILE"
Michael Mrozek
quelle
Gute Antwort; $HISTFILEkönnte Leerzeichen enthalten, die es wahrscheinlich wert sind, zitiert zu werden.
Chris Down
Vorsicht ... Histfile ist unvorhersehbar, wenn Sie viele offene Shells haben, ist es nicht abzusehen, was genau gespeichert wird und in welcher Reihenfolge. Kann jemand bestätigen, dass bereits geöffnete Shells den Verlauf, den sie bei der Initialisierung geladen haben, beim Schließen nicht neu schreiben?
Orion
8

Die Antwort von Michael Mrozek funktioniert, wenn Sie keine Lust haben, Befehle aus der aktuellen Sitzung zu entfernen. Wenn Sie dies tun, sollten Sie in die Verlaufsdatei schreiben, bevor Sie die Vorgänge in seinem Beitrag ausführen history -a.

Auch nachdem Sie die Einträge entfernt , die Sie aus Ihrer History - Datei möchten, können Sie es durch die Ausgabe neu zu laden history -c, dann history -r.

Chris Down
quelle
2

Basierend auf den Antworten von Michael und Chris habe ich Folgendes gefunden. Fügen Sie es Ihrer ~/.bashrcDatei hinzu und laden Sie es dann mit . ~/.bashrcoder 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
}
Aliteralmind
quelle
2

Für diejenigen, die einen Einzeiler suchen:

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

Wenn Sie also z. Löschen Sie mehrere Zeilen mit einem Passwort. Ersetzen Sie einfach "SEARCH_STRING_GOES_HERE" durch das Passwort. Dadurch wird der gesamte Verlauf nach dieser Suchzeichenfolge durchsucht und gelöscht.

2 Dinge, die Sie beachten sollten

  • grep verwendet reguläre Ausdrücke, sofern Sie nicht -F als Argument angeben
  • Der Befehl zeigt 1 Fehler an, sobald keine Übereinstimmungen mehr vorliegen. Ignoriere es.
daslogix
quelle
Ich habe eine Fehlermeldung erhalten (-bash: history: -d: option erfordert ein Argument), aber es hat trotzdem funktioniert?
Paradroid
Der Löschbefehl wird so lange ausgeführt, bis ein Fehler auftritt (da nichts mehr zu löschen ist). Ignoriere einfach den Fehler.
Thelogix
1
cat "$HISTFILE" | grep -v "commandToDelete" >> "$HISTFILE" && exit

Das hat bei mir funktioniert. history -c && history -a hat die Verlaufsdatei für mich nicht richtig neu geladen. Stattdessen beende ich meine Sitzung direkt nach dem Überschreiben der Verlaufsdatei, damit diese von der gespeicherten nicht überschrieben wird.

Hydde87
quelle