Bagaimana cara menghapus perintah dalam riwayat yang cocok dengan string yang diberikan?

13

Saya perlu menghapus semua perintah dalam riwayat saya yang cocok dengan string. Saya sudah mencoba:

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

Apa cara yang tepat untuk melakukan ini?

perbaikan linux
sumber
Meskipun ada jawaban yang berfungsi di bawah, saya masih bertanya-tanya mengapa itu tidak berhasil history -d X. Saya menemukan pertanyaan ini karena saya baru saja selesai history | grep search_str | sort -nr | awk '{print $1}' | while read i; do history -d $i; done. Tidak ada kesalahan, tetapi tidak ada yang dihapus. Adakah yang bisa menjelaskan mengapa?
mivk

Jawaban:

18

The historyperintah hanya beroperasi pada file history Anda, $HISTFILE(biasanya ~/.historyatau ~/.bash_history). Ini akan jauh lebih mudah jika Anda hanya menghapus garis dari file itu, yang dapat dilakukan dengan banyak cara. grepadalah salah satu cara, tetapi Anda harus berhati-hati untuk tidak menimpa file saat masih membacanya:

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

Cara lain adalah dengan sed:

$ sed -i '/searchstring/d' "$HISTFILE"
Michael Mrozek
sumber
Jawaban yang bagus; $HISTFILEdapat berisi spasi, mungkin layak dikutip.
Chris Down
Hati-hati ... histfile tidak dapat diprediksi, jika Anda memiliki banyak kerang yang terbuka, tidak ada yang tahu persis apa yang akan diselamatkan dan dalam urutan apa. Adakah yang bisa mengkonfirmasi bahwa kerang yang sudah terbuka tidak akan menulis ulang riwayat yang mereka muat saat inisialisasi, ketika ditutup?
orion
8

Jawaban Michael Mrozek akan bekerja jika Anda tidak peduli tentang menghapus perintah dari sesi saat ini. Jika Anda melakukannya, Anda harus menulis ke file riwayat sebelum melakukan operasi di posnya dengan melakukan history -a.

Juga, setelah Anda menghapus entri yang Anda inginkan dari file riwayat Anda, Anda dapat memuatnya kembali dengan menerbitkan history -c, lalu history -r.

Chris Down
sumber
2

Berdasarkan jawaban Michael dan Chris , saya datang dengan yang berikut. Tambahkan ke ~/.bashrcfile Anda dan kemudian memuatnya dengan . ~/.bashrcatau 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
sumber
2

Bagi mereka yang mencari one-liner:

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

Jadi, jika Anda ingin misalnya. hapus beberapa baris dengan kata sandi di dalamnya, cukup ganti "SEARCH_STRING_GOES_HERE" dengan kata sandi. Ini akan mencari seluruh riwayat Anda untuk string pencarian itu dan menghapusnya.

2 hal yang harus diperhatikan

  • grep menggunakan regex kecuali Anda memberikan -F sebagai argumen
  • Perintah akan menampilkan 1 kesalahan, setelah tidak ada lagi yang cocok. Abaikan itu.
thelogix
sumber
Saya mendapat kesalahan (-bash: history: -d: opsi membutuhkan argumen), tetapi masih berfungsi?
paradroid
Ini menjalankan perintah delete terus menerus, sampai gagal dengan kesalahan (karena tidak ada lagi yang perlu dihapus). Abaikan saja kesalahannya.
thelogix
1
cat "$HISTFILE" | grep -v "commandToDelete" >> "$HISTFILE" && exit

Ini berhasil untuk saya. history -c && history -a tidak memuat ulang file history dengan benar untuk saya. Jadi alih-alih saya hanya keluar dari sesi saya tepat setelah menulis ulang file histori sehingga yang ada di memori tidak menimpanya.

Hydde87
sumber