Как удалить команды в истории, соответствующие заданной строке?

13

Мне нужно удалить все команды в моей истории, соответствующие строке. Я пробовал:

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

Как правильно это сделать?

linuxfix
источник
Хотя ниже приведены рабочие ответы, я все еще удивляюсь, почему они не работают history -d X. Я столкнулся с этим вопросом, потому что я только что сделал history | grep search_str | sort -nr | awk '{print $1}' | while read i; do history -d $i; done. Нет ошибки, но ничего не удалено. Кто-нибудь может объяснить почему?
mivk

Ответы:

18

Команда historyработает только с вашим файлом истории $HISTFILE(обычно ~/.historyили ~/.bash_history). Будет гораздо проще, если вы просто удалите строки из этого файла, что можно сделать разными способами. grepЭто один из способов, но вы должны быть осторожны, чтобы не перезаписать файл во время его чтения:

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

Другой способ с sed:

$ sed -i '/searchstring/d' "$HISTFILE"
Михаил Мрозек
источник
Хороший ответ; $HISTFILEможет содержать пробелы, вероятно, стоит цитировать его.
Крис Даун
Осторожно ... история непредсказуема, если у вас много открытых оболочек, невозможно сказать, что именно будет сохранено и в каком порядке. Кто-нибудь может подтвердить, что уже открытые оболочки не переписывают историю, загруженную при инициализации, когда они закрыты?
Орион
8

Ответ Михаэля Мрозека сработает, если вы не хотите удалять команды из текущего сеанса. Если вы это сделаете, вы должны записать в файл истории, прежде чем делать операции в своем посте, выполнив history -a.

Кроме того, после того, как вы удалили нужные записи из файла истории, вы можете перезагрузить их, выполнив history -c, затем history -r.

Крис Даун
источник
2

Основываясь на ответах Майкла и Криса , я придумал следующее. Добавьте его в свой ~/.bashrcфайл , а затем загрузить его либо . ~/.bashrcили 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
источник
2

Для тех, кто ищет однострочник:

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

Так что, если вы хотели, например. удалите несколько строк с паролем, просто замените «SEARCH_STRING_GOES_HERE» на пароль. Это будет искать всю историю поиска для этой строки поиска и удалить ее.

2 вещи, которые нужно знать

  • grep использует регулярные выражения, если вы не указали -F в качестве аргумента
  • Команда покажет 1 ошибку, если совпадений больше нет. Игнорируй это.
thelogix
источник
Я получил ошибку (опция -bash: history: -d: требует аргумента), но она все еще работает?
paradroid
Он выполняет команду удаления непрерывно, пока не завершится с ошибкой (потому что больше нечего удалять). Просто игнорируйте ошибку.
Thelogix
1
cat "$HISTFILE" | grep -v "commandToDelete" >> "$HISTFILE" && exit

Это сработало для меня. history -c && history -a неправильно перезагрузила файл истории для меня. Поэтому вместо этого я просто выхожу из сеанса сразу после перезаписи файла истории, чтобы тот, который находится в памяти, не перезаписывал его.

Hydde87
источник