特定の文字列に一致する履歴のコマンドを削除するにはどうすればよいですか?


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)

これを行う正しい方法は何ですか?


以下に有効な答えがありますが、なぜそれが動作しないのか疑問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これは1つの方法ですが、ファイルを読み取り中に上書きしないように注意する必要があります。

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

別の方法はsed次のとおりです。

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

いい答えです; $HISTFILEおそらく引用する価値があるスペースを含めることができます。
クリスダウン

注意... histfileは予測不可能です。開いているシェルが多数ある場合、何が正確にどの順序で保存されるかはわかりません。誰でも、すでに開いているシェルが閉じられたときに、初期化時にロードした履歴を書き換えないことを確認できますか?
オリオン

8

現在のセッションからコマンドを削除してもかまわない場合は、Michael Mrozekの回答が有効です。そうした場合、彼の投稿で操作を行う前に、履歴ファイルに書き込む必要があります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
}

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つのこと

  • 引数として-Fを指定しない限り、grepは正規表現を使用します
  • 一致するものがなくなると、コマンドは1つのエラーを表示します。それを無視します。

エラーが発生しました(-bash:history:-d:オプションには引数が必要です)が、それでも動作しますか?
パラドロイド

エラーで失敗するまで、削除コマンドを継続的に実行します(削除するものがもうないため)。エラーを無視してください。
thelogix

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

これは私のために働いた。history -c && history -aは、履歴ファイルを適切にリロードしませんでした。代わりに、メモリ内のファイルが上書きしないように、履歴ファイルを書き換えた直後にセッションを終了します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.