Hapus baris tertentu dari file Bash history

Jawaban:

108

Anda harus keluar dan kembali atau menjalankan history -asehingga riwayat saat ini berkomitmen untuk disk.

Kemudian cukup edit file ~/.bash_history.

cYrus
sumber
19
Jika variabel lingkungan HISTFILE diatur, file histori bukan ~ / .bash_history tetapi $ {HISTFILE}.
Karolos
20
Entri ditulis ke dalam file histori ketika Anda keluar dari shell. Oleh karena itu, setelah memasukkan perintah yang ingin Anda hapus, Anda harus keluar dan kembali, atau menggunakan 'history -d xxxx' untuk menghapusnya dari sesi shell saat ini.
Berbahaya
3
tetapi bagaimana Anda menghapus catatan mengedit file histori?
chiliNUT
5
@chiliNUT: Mulai saja perintah Anda (mis. vim ~/.bash_history) dengan spasi; perintah yang dimulai dengan spasi biasanya tidak dicatat (lihat $HISTCONTROL).
cYrus
Saya tidak berpikir itulah yang terjadi dalam distribusi saya, tetapi secara umum itu masuk akal
cabeNUT
149

Anda dapat menghapus dari file histori menggunakan commandline dalam dua langkah:

  1. Mengetik history -d <line_number>menghapus baris yang ditentukan dari riwayat di memori.
  2. Mengetik history -wmenulis riwayat memori saat ini ke ~/.bash_historyfile.

Dua langkah bersama-sama menghilangkan garis permanen dari dalam memori sejarah dan dari Bash_history file juga.

Paperlantern
sumber
7
bagaimana cara menghapus yang terakhir history -wdari riwayat?
KrIsHnA
@KrIsHnA sunting ~ / .bash_history secara manual
Alexander Myshov
5
Atau tambahkan spasi sebelum itu agar tidak ditambahkan, seperti dalam jawaban @ tao
Mark
Untuk menemukan <line_number>hanya history | grep [unwanted_content]untuk mendapatkan daftar dengan semua baris yang berisi [unwanted_content](seperti kata sandi).
AvL
Bagaimana Anda menghapus beberapa baris (khusus) (berdasarkan id)?
Pathros
39

Untuk mencegah perintah agar tidak ditambahkan ke riwayat, pastikan bahwa variabel lingkungan HISTCONTROLberisi nilai yang dipisahkan dengan titik duanya ignorespace, misalnya (tambahkan misalnya ke .bashrc):

$ export HISTCONTROL=ignorespace

Ini akan mencegah perintah apa pun dengan ruang terkemuka ditambahkan ke histori. Anda kemudian dapat menghapus riwayat sepenuhnya dengan menjalankan

$  history -c -w
  ^-- additional space character
tao
sumber
32

Pertama-tama, jika perintah yang akan Anda keluarkan sensitif, tidak aman, atau Anda hanya tidak membutuhkannya mengacaukan sejarah Anda, yang terbaik / tercepat untuk mencegahnya memasukkan sejarah di tempat pertama. Pastikan itu $HISTCONTROLmengandung ignorespace:

(bash)$ echo $HISTCONTROL
ignoredups:ignorespace

Kemudian, lanjutkan perintah apa pun yang tidak Anda inginkan dalam riwayat Anda dengan spasi:

(bash)$  sensitive-cmd-with --password 82cf7dfe
(bash)$  rm -r... # One-off recursive remove; mustn't be accidentally repeated!

Jika Anda secara tidak sengaja memasukkan perintah yang tidak diinginkan ke dalam riwayat, asalkan sesi bash Anda masih terbuka, perintah tersebut belum menyentuh disk. Untuk menghapus perintah sebelumnya dalam riwayat, terbitkan:

(bash)$  history -d $((HISTCMD-1))

Perhatikan ruang terdepan; perintah ini membutuhkan ignorespace, jika tidak, itu hanya akan menghapus sendiri!

Jika Anda ingin menghapus beberapa perintah terakhir, temukan nomor riwayat terakhir dan pertama:

(bash)$  history 5
  598  ok
  599  sensitive
  600  unsafe
  601  doesn\'t-work
  602  otherwise-unwanted

Dalam hal ini 602 dan 599. Kemudian terbitkan:

(bash)$  for i in {602..599}; do history -d $i; done

(Tanpa ignorespace, itu akan menjadi 603..599.)

Jika Anda tidak ingin riwayat apa pun dari sesi Anda saat ini mengenai disk, keluar menggunakan:

(bash)$ kill -9 $$

Pendekatan sejauh ini adalah untuk tidak membiarkan item sejarah sensitif ditulis ke disk untuk keamanan tambahan, karena dalam teori data yang dihapus dari media non-volatile masih dapat dipulihkan.

Namun, jika perintah yang ingin Anda hapus berasal dari sesi sebelumnya, mereka sudah ditambahkan pada saat $HISTFILEkeluar. Memanipulasi sejarah dengan perintah di atas masih akan hanya menambahkan item baru yang tersisa ke $HISTFILE, pada saat keluar . Untuk menimpa para $HISTFILEdengan pandangan sesi saat ini dari seluruh sejarah, sekarang , masalah:

(bash)$  history -w

Tentu saja untuk item histori yang sudah ada di disk, alternatif untuk mengedit histori dengan history -dperintah yang kemudian dikeluarkan history -w, adalah mengedit $HISTFILEdengan editor teks.

James Haigh
sumber
1
"Memanipulasi sejarah dengan perintah di atas masih akan hanya menambahkan item baru yang tersisa ke $HISTFILE, saat keluar ." Sebenarnya, ini tidak sepenuhnya benar. Tampaknya hanya menambahkan item baru yang tersisa yang 'menonjol' dari panjang sejarah asli. Misalnya, jika saya menghapus 5 item asli dan menambahkan 15 item baru, hanya 10 item baru ditambahkan, sedangkan saya berharap semua 15 item baru ditambahkan. Saya pikir ini adalah bug karena saya tidak dapat melihat bagaimana ini merupakan fungsi yang diinginkan.
James Haigh
1
Saya kira bash mencatat panjang aslinya. Pada penutupan sesi, mungkin ditambahkan item yang jumlahnya lebih besar dari nilai ini. Jika nilai ini dikurangi setiap kali item dihapus yang jumlahnya kurang dari atau sama dengan nilai ini, itu akan berfungsi seperti yang diharapkan. ;-)
James Haigh
15

Beberapa teknik:

Cegah agar informasi sensitif tidak disimpan dalam file histori

Jika Anda memasukkan beberapa kata sandi pada baris perintah, maka sadari bahwa semua perintah dicatat, Anda bisa:

  1. Keluar paksa dari sesi saat ini tanpa menyimpan riwayat:

     kill -9 $$

    Ini akan menghapus semua riwayat saat ini.

  2. Ketik ↑ (up arrow)sesi bash terbuka hingga informasi sensitif ditampilkan, kemudian gunakan penekanan tombol pengeditan seperti Ctrl+ Wuntuk menghapus info sensitif, dan kemudian ↓ (down arrow) sampai baris kosong baru diminta, sebelum mengetik Enter.

Hapus informasi sensitif dari file riwayat

Jika Anda menyadari bahwa informasi sensitif sudah disimpan, dan Anda ingin menghapusnya, tetapi tidak seluruh riwayat Anda:

sedPerintah sederhana dapat melakukan pekerjaan:

sed -e '/SeNsItIvE InFo/d' -i .bash_history

tetapi, saat Anda mengetik ini, Anda membuat garis riwayat lain yang berisi pola pencarian (info sensitif) yang Anda coba hapus. Jadi kamu bisa:

sed -e "/$(head -n1)/d" -i .bash_history

Ini akan berjalan head -n1dengan input dari terminal. Akan terlihat bahwa terminal Anda digantung (tidak akan ada prompt); cukup ketik informasi yang ingin Anda hapus dari file. Ini adalah trik untuk membiarkan Anda memasukkan (bagian dari) perintah tanpa benar-benar mengetiknya ke dalam baris perintah, sehingga membuatnya tidak memenuhi syarat untuk dimasukkan dalam catatan sejarah. Kemudian sedakan menggunakan teks yang Anda ketikkan untuk mencari .bash_history dan menghapus semua baris yang berisi info sensitif. Catatan: jika pola informasi sensitif Anda berisi garis miring, Anda harus menghindarinya dengan garis miring terbalik, atau ubah sedperintah untuk menggunakan sintaks ini untuk menentukan pembatas yang tidak muncul dalam pola:

sed -e "\|$(head -n1)|d" -i .bash_history

Cara lain bisa dengan menghapus hanya informasi sensitif, tetapi tetap memegang perintah yang berisi informasi. Untuk ini, Anda cukup mengganti informasi sensitif dengan teks pengganti pilihan Anda:

sed -e "s/$(head -n1)/Santa Claus/g" -i .bash_history.

Hapus informasi sensitif dari file apa pun di pohon tertentu

Akhirnya, untuk memastikan bahwa ini tidak akan tetap di file lain yang dilupakan:

SENSITIVEINFO="$(head -n1)"
find . -type f -print0 | xargs -0 grep -l "$SENSITIVEINFO"

akan mendaftar semua file terkait.

find . -type f -print0 |
    xargs -0 grep -l "$SENSITIVEINFO" |
    tr \\n \\0 |
    xargs -0 sed -e "s/$SENSITIVEINFO/Santa Claus/g" -i

akan mengganti semua kemunculan info sensitif di semua file di pohon direktori yang di-root di .. Catatan: meskipun perintah ini digunakan xargs -0, ia tidak akan menangani file dengan baris baru dalam namanya.

F. Hauri
sumber
11

Temukan baris yang ingin Anda hapus dengan menekan ↑ (up arrow)sampai muncul, lalu tekan Ctrl+ U. Itu harus menghapus garis.

Jika Anda menggunakan historyperintah, Anda dapat melihat baris telah diganti dengan tanda bintang.

vicentecarro
sumber
2
Sebenarnya, saya percaya bahwa Anda harus mengarahkan kursor ke baris, tekan Ctrl + U, dan kursor ke atas atau ke bawah ke baris lain (mungkin yang kosong di bagian bawah daftar). Juga, sebenarnya, garis belum diganti dengan tanda bintang. Sebaliknya, perintah telah dihapus, dan nomor riwayat telah ditambahkan dengan a *.
G-Man
1
Ini menjadi jauh lebih kuat dengan Ctrl + R (membalikkan pencarian sejarah inkremental), lalu misalnya [Akhir], Ctrl + U
sehe
4

Jika Anda perlu menghapus beberapa baris secara bersamaan saya biasanya menggunakan ini:

history | grep <string> | cut -d ' ' -f 3 | awk '{print "history -d " $1}'

Jika Anda perlu menghapus perintah terakhir yang dapat Anda gunakan:

history -d $((HISTCMD-2))
Obligasi
sumber
2
Ini kelihatannya berhasil tetapi history | grep <string>masih menunjukkan semua baris yang diklaimnya dihapus ...
Brock Hensley
1
Ini akan menghapus baris histori yang salah setelah menghapus fisrt !!
mivk
1
Tapi untungnya, itu hanya mencetak perintah hapus yang salah. Berikut ini akan mencetak perintah hapus yang benar:history | grep XYZ | grep -v grep | tac | awk '{print "history -d", $1}'
mivk
3

Jika Anda perlu menghapus serangkaian garis dari riwayat, fungsi bash berikut dapat menghemat waktu Anda:

function histdel() {
    [ $# -eq 1 ] && history -d "$1" && history -w
    if [ $# -eq 2 -a "$1" -le "$2" ]; then
        for n in `seq "$2" "$1"`; do
            history -d "$n"
        done
        history -w
    fi
}

Fungsi biasanya ditambahkan ke $HOME/.bashrc. Untuk menggunakan fungsi imediatelly, Anda harus meminta file dibaca lagi oleh shell Anda yang berjalan ( . $HOME/.bashrc). Kemudian untuk menghapus mis perintah 200-210 dari riwayat:

$ histdel 200 210

(Catatan: Pertanyaan ini adalah salah satu hasil pencarian teratas jika Anda mencari menghapus serangkaian perintah dari sejarah bash. Jadi, sementara pertanyaan di atas lebih dari apa yang ditanyakan, itu bisa berguna bagi beberapa pembaca.)

m000
sumber
3
Bentuk-bentuk alternatif untuk forpernyataan: for n in $(seq "$2" "$1")lebih disukai oleh sebagian orang, dan, jika seqtidak berhasil, coba for ((n="$2"; n>="$1"; n--)).
Scott
3
history | sed -i 59d

59 adalah nomor baris. Tidak bisa lebih manis dari ini :)

KroKite
sumber
3

Coba saja ini,

$ history

ini akan menampilkan id sejarah dan perintah, mis

.
.
211 ls
212 javac Welcome.java
213 java welcome
.
.

menggunakan,

$ history -d 211

Di sini 211 adalah id sejarah. Sekarang periksa ini menggunakan

$ history

.
.
211 javac Welcome.java
212 java welcome
.
.

pengguna3378188
sumber
2

Saya tahu ini sudah lama sejak pertanyaan ini ditanyakan dan dijawab, tetapi saya akan menunjukkan kepada Anda metode saya untuk membersihkan file riwayat saya dan keluar pada saat yang sama.

Saya berlari : history -w && nano "${HISTFILE}" && history -c && exit

Apa yang dilakukannya sederhana:

  1. history -w : menulis sejarah dalam cache "${HISTFILE}"
  2. nano "${HISTFILE}": izinkan saya untuk mengedit "${HISTFILE}"Anda dapat menggunakan skrip sed atau apa pun yang Anda ingin bersihkan"${HISTFILE}"
  3. history -c : hapus riwayat cache sehingga perintah terakhir ini tidak ditambahkan.
  4. exit : logout saya tambahkan riwayat cache ... tapi kosong;)

Setelah perintah itu, Anda akan keluar dengan file histori bersih. Masuk untuk memeriksa riwayat Anda;)

Saya harap ini akan membantu seseorang.

ncenerar
sumber
1

Anda juga dapat mengedit file histori secara langsung, misalnya nano .bash_historyjika Anda berada di bash shell?

Ducky
sumber