Bagaimana cara menghapus riwayat 10 perintah terakhir di shell?

131

Perintah berikut

  511  clear
  512  history
  513  history -d 505
  514  history
  515  history -d 507 510 513
  516  history
  517  history -d 509
  518  history
  519  history -d 511
  520  history

Saya dapat menghapus satu per satu history -d 511, tetapi bagaimana cara menghapus 10 perintah terakhir dan di antara 10 perintah sejarah menggunakan perintah tunggal di shell?

Bisakah kita menulis skrip bash dan mengeksekusi untuk penghapusan sejarah?

Justin John
sumber
18
vi $HISTFILEdan hapus yang Anda inginkan. Gunakan head -n -10jika Anda harus mengotomatiskannya.
Anton Kovalenko
Apakah pertanyaan ini di luar topik ? atau Ini bukan tempat yang tepat untuk menanyakan pertanyaan seperti ini? Jika demikian, di mana saya harus mengajukan pertanyaan ini, maksud saya di mana dalam pertukaran tumpukan?
Justin John
1
Perintah Shell berfungsi sama apakah Anda masuk secara lokal atau melalui ssh.
Barmar
2
Unix dan Linux StackExchange (unix.stackexchange.com) mungkin merupakan tempat yang lebih baik untuk pertanyaan ini. Ini di luar topik di sini karena tidak berhubungan dengan pemrograman.
Dan Moulding
4
Memprogram skrip shell adalah solusi ideal untuk pertanyaan ini, akibatnya harus dipertimbangkan terkait dengan pemrograman. Belum lagi fakta bahwa OP sebenarnya meminta skrip khusus.
SSH

Jawaban:

109

Sudahkah Anda mencoba mengedit file riwayat secara langsung:

~/.bash_history
Di mana saja
sumber
2
@WherethereisaWill OP ingin skrip, bukan plug and chug manual.
Tyler Jandreau
10
akan mulai berlaku setelah meluncurkan kembali (menutup dan membuka kembali) terminal
khaled_webdev
8
Jika Anda melakukan ini dengan vim Anda dapat menemukan riwayat penghapusan Anda ~/.viminfojadi pastikan untuk menghapusnya juga!
waltwood
5
kadang-kadang disimpan dalam memori dan pengeditan manual tidak akan bertahan setelah login berikutnya ..
superhero
5
@FizerKhan Maksud saya bahwa perubahan yang dibuat .bash_historydapat ditimpa oleh apa yang disimpan dalam memori. Saya menemukan solusi ini bermanfaat: superuser.com/a/384383/253543
superhero
73

Jawaban saya didasarkan pada jawaban sebelumnya, tetapi dengan penambahan membalik urutan sehingga item riwayat dihapus dari yang terbaru ke yang paling baru.

Dapatkan riwayat Anda saat ini (sesuaikan jumlah garis yang ingin Anda lihat):

history | tail -n 10

Ini memberi saya sesuatu seperti

1003  25-04-2016 17:54:52 echo "Command 1"
1004  25-04-2016 17:54:54 echo "Command 2"
1005  25-04-2016 17:54:57 echo "Command 3"
1006  25-04-2016 17:54:59 echo "Command 4"
1007  25-04-2016 17:55:01 echo "Command 5"
1008  25-04-2016 17:55:03 echo "Command 6"
1009  25-04-2016 17:55:07 echo "Command 7"
1010  25-04-2016 17:55:09 echo "Command 8"
1011  25-04-2016 17:55:11 echo "Command 9"
1012  25-04-2016 17:55:14 echo "Command 10"

Pilih posisi awal dan akhir untuk item yang ingin Anda hapus. Saya akan menghapus entri 1006 hingga 1008.

for h in $(seq 1006 1008); do history -d 1006; done

Ini akan menghasilkan history -dperintah untuk 1006, kemudian 1007 menjadi 1006 dan 1006 dihapus, maka 1008 (menjadi 1007) sekarang 1006 dan dihapus.

Jika saya juga ingin menghapus perintah delete history maka itu sedikit lebih rumit karena Anda perlu mengetahui entri max history saat ini.

Anda bisa mendapatkan ini dengan (mungkin ada cara yang lebih baik):

history 1 | awk '{print $1}'

Menyatukannya Anda dapat menggunakan ini untuk menghapus rentang, dan juga menghapus perintah hapus riwayat:

for h in $(seq 1006 1008); do history -d 1006; done; history -d $(history 1 | awk '{print $1}')

Bungkus semuanya dalam fungsi untuk ditambahkan ke ~/.bashrc:

histdel(){
  for h in $(seq $1 $2); do
    history -d $1
  done
  history -d $(history 1 | awk '{print $1}')
  }

Contoh menghapus perintah 4, 5 dan 6 (1049-1051) dan menyembunyikan bukti:

[18:21:02 jonathag@gb-slo-svb-0221 ~]$ history 11
 1046  25-04-2016 18:20:47 echo "Command 1"
 1047  25-04-2016 18:20:48 echo "Command 2"
 1048  25-04-2016 18:20:50 echo "Command 3"
 1049  25-04-2016 18:20:51 echo "Command 4"
 1050  25-04-2016 18:20:53 echo "Command 5"
 1051  25-04-2016 18:20:54 echo "Command 6"
 1052  25-04-2016 18:20:56 echo "Command 7"
 1053  25-04-2016 18:20:57 echo "Command 8"
 1054  25-04-2016 18:21:00 echo "Command 9"
 1055  25-04-2016 18:21:02 echo "Command 10"
 1056  25-04-2016 18:21:07 history 11
[18:21:07 jonathag@gb-slo-svb-0221 ~]$ histdel 1049 1051
[18:21:23 jonathag@gb-slo-svb-0221 ~]$ history 8
 1046  25-04-2016 18:20:47 echo "Command 1"
 1047  25-04-2016 18:20:48 echo "Command 2"
 1048  25-04-2016 18:20:50 echo "Command 3"
 1049  25-04-2016 18:20:56 echo "Command 7"
 1050  25-04-2016 18:20:57 echo "Command 8"
 1051  25-04-2016 18:21:00 echo "Command 9"
 1052  25-04-2016 18:21:02 echo "Command 10"
 1053  25-04-2016 18:21:07 history 11

Pertanyaannya sebenarnya adalah menghapus 10 perintah terakhir dari histori, jadi jika Anda ingin menyimpan sedikit usaha, Anda bisa menggunakan fungsi lain untuk memanggil histdelfungsi yang melakukan perhitungan untuk Anda.

histdeln(){

  # Get the current history number
  n=$(history 1 | awk '{print $1}')

  # Call histdel with the appropriate range
  histdel $(( $n - $1 )) $(( $n - 1 ))
  }

Fungsi ini membutuhkan 1 argumen, jumlah item riwayat sebelumnya untuk dihapus. Jadi untuk menghapus 10 perintah terakhir dari riwayat cukup gunakan histdeln 10.

JGC
sumber
history | tail -1 | awk '{print $1}'dapat disederhanakan menjadihistory 1 | awk '{print $1}'
George Hilliard
-bash: tac: command not foundpada Mac OSX, jika tidak, ini akan menjadi jawaban terbaik.
Zim
for h in $(seq 1006 1008); do history -d 1006; doneini berfungsi di ubuntu 16.04
mahfuz
Singkat tapi manis:for i in {1..10}; do history -d $(($HISTCMD-11)); done
alkimia
30
for x in `seq $1 $2`
do
  history -d $1
done
Barmar
sumber
3
Pastikan untuk menggunakan angka yang lebih tinggi untuk argumen pertama atau Anda akan menghapus setiap perintah lainnya. Misalnya ketika perintah 511 dihapus, semuanya bergeser ke bawah sehingga 512 menjadi 511 baru dan 513 adalah 512 baru. Oleh karena itu history -d 511berfungsi seperti yang diharapkan, kemudian history -d 512menghapus apa yang dulunya 513, dan 512 tetap dalam sejarah sebagai perintah 511. Harapan itu masuk akal .
Matius
5
@ Matius Itu tidak perlu. Saya tidak menghapus $xsetiap kali melalui loop, saya menghapus $1. Jadi pertama menghapus 511, dan 512 menjadi 511. Kemudian menghapus 511 lagi, dan seterusnya.
Barmar
@Matthew Perhatikan bahwa saya membuat komentar yang mirip dengan jawaban Tyler. Saya datang dengan solusi saya sebagai perbaikan untuk itu.
Barmar
Anda benar, tergesa-gesa ketika menulis ini dalam satu baris di bash prompt saya, saya menggunakan for i in... dan history -d $idan mendapatkan hasil yang saya jelaskan dalam komentar saya di atas. Menggunakan $ 1 ini benar-benar benar seperti yang dinyatakan dalam jawaban asli Anda.
Matius
18

Pertama, ketik: historydan tuliskan urutan nomor baris yang ingin Anda hapus.

Untuk menghapus baris dari katakanlah baris 1800 hingga 1815 tulis yang berikut di terminal:

$ for line in $(seq 1800 1815) ; do history -d 1800; done

Jika Anda ingin menghapus histori untuk perintah penghapusan, tambahkan +1 untuk 1815 = 1816 dan histori untuk urutan itu + perintah penghapusan akan dihapus.

Sebagai contoh :

$ for line in $(seq 1800 1816) ; do history -d 1800; done
Ghassan Zein
sumber
Saya membuat pembaruan tetapi masih tidak berfungsi dengan benar di Ubuntu 12.04 .. :( Sepertinya bagian nomor baris tidak berfungsi dengan benar
Binod Kalathil
Saya menolak sunting yang disarankan Binod karena itu bukan kesalahan logis. Kode asli Ghassan menggunakan pendekatan yang sama dengan jawaban Barmar - yang berfungsi. Komentar untuk jawaban Barmar menjelaskan mengapa saran mengganti 1800 dengan $linemenghapus setiap baris lainnya dan kemudian melebihi kisaran yang diinginkan.
Anthony Geoghegan
18

Dengan Bash 5 sekarang Anda dapat melakukan range ... Hore !:

history -d 511-520

atau menghitung mundur 10:

history -d -10--1

Kutipan dari Bash 5 Man Page :

'sejarah'

Opsi, jika disediakan, memiliki arti sebagai berikut:

'-d OFFSET' Hapus entri riwayat di posisi OFFSET. Jika OFFSET positif, itu harus ditentukan seperti yang muncul ketika histori ditampilkan. Jika OFFSET negatif, itu ditafsirkan sebagai relatif terhadap yang lebih besar dari posisi sejarah terakhir, jadi indeks negatif menghitung mundur dari akhir sejarah, dan indeks '-1' mengacu pada perintah 'history -d' saat ini.

'-d START-END' Menghapus entri riwayat antara posisi MULAI dan AKHIR, inklusif. Nilai positif dan negatif untuk MULAI dan AKHIR ditafsirkan seperti yang dijelaskan di atas.

Inilah solusi saya untuk Bash 4. Ini menghapus secara berulang entri tunggal atau rentang sejarah dimulai dengan indeks terendah.

delHistory () {
    count=$(( ${2:-$1} - $1 ))
    while [[ $count -ge 0 ]]; do
        history -d "$1"
        ((count--))
    done
}

delHistory 511 520
David Hatch
sumber
14

Menggabungkan jawaban dari atas:

history -w vi ~/.bash_history history -r

Bryant Bernstein
sumber
9

edit:

Mengubah iterator yang diperkuat, panggilan bagus. Juga, panggil fungsi ini dengan iterator terbalik.

Anda mungkin dapat melakukan sesuatu seperti ini:

#!/bin/bash
HISTFILE=~/.bash_history   # if you are running it in a 
                           # non interactive shell history would not work else
set -o history
for i in `seq $1 $2`;
do
    history -d $i
done
history -w

Di mana Anda akan membangkitkan seperti ini:

./nameOfYourScript 563 514

Perhatikan Saya belum memasukkan kesalahan saat memeriksa batas. Saya akan meninggalkan itu sebagai latihan untuk pembaca.

lihat juga pertanyaan ini

Tyler Jandreau
sumber
6
Setelah Anda menghapus 510, 511 menjadi 510, 512 menjadi 511, dan seterusnya. Jadi ini akan menghapus setiap baris lainnya.
Barmar
Anda tidak bisa memasukkan variabel dalam ekspansi brace.
chepner
seq 563 514tidak akan mencetak apa pun. Kamu butuh seq 563 -1 514. Sebagai alternatif, Anda cukup menggunakan history -d $1argumen sebagai514 563
anishsane
9

Mungkin akan bermanfaat bagi seseorang.
Ketika Anda login ke pengguna manapun dari konsol / terminal riwayat sesi Anda saat ini hanya ada di beberapa "buffer" yang flushes ke ~ / .bash_history pada logout Anda.
Jadi, untuk merahasiakannya, Anda bisa:
history -r && exit
dan Anda akan keluar dengan riwayat semua sesi Anda (dan hanya);)

Alex
sumber
5

Saya menggunakan kombinasi solusi yang dibagikan di utas ini untuk menghapus jejak dalam sejarah perintah. Pertama, saya memverifikasi di mana riwayat perintah tersimpan dengan:

echo $HISTFILE

Saya mengedit sejarah dengan:

vi <pathToFile>

Setelah itu, saya membersihkan buffer riwayat sesi saat ini dengan:

history -r && exit

Lain kali Anda masuk ke sesi ini, perintah terakhir yang akan Anda lihat pada sejarah perintah adalah yang terakhir yang Anda tinggalkan di pathToFile .

M. Gleria
sumber
ini berfungsi untuk saya, untuk jawaban dari @jgc, ketika saya login lagi ke server, sejarah kembali lagi, hanya berfungsi untuk sesi yang masuk
Yogeshwar Tanwar
1

history -c akan menghapus semua histori.

pengguna6280539
sumber
1

untuk menghapus 10 entri terakhir (berdasarkan pada contoh Anda):

history -d 511 520
Filsuf
sumber
1
Dalam GNU bash, versi 4.3.11 (1) ini hanya menghapus baris pertama dalam daftar
Gary
1

Saya menggunakan skrip ini untuk menghapus 10 perintah terakhir dalam sejarah:

pos=$HISTCMD; start=$(( $pos-11 )); end=$(( $pos-1 )); for i in $(eval echo "{${start}..${end}}"); do history -d $start; done

Ia menggunakan $HISTCMDlingkungan var untuk mendapatkan indeks riwayat dan menggunakannya untuk menghapus 10 entri terakhir di history.

Junaid
sumber
1

Coba yang berikut ini:

for i in {511..520}; do history -d $i; echo "history -d $i"; done
rb1234
sumber
Itu mengasumsikan dia sudah mendaftarkan sejarah dan mengetahui semua ID sebelumnya
Markoorn
dan itu tidak bisa menjadi yang terakhir dalam daftar sejarah, jika tidak: "posisi sejarah di luar jangkauan"
devwebcl
harus:for i in {511..520}; do history -d $i; echo "history -d 511"; done
devwebcl
1

Saya menggunakan ini (saya memiliki bash 4):

histrm() {
    local num=${1:- 1}
    builtin history -d $(builtin history | sed -rn '$s/^[^[:digit:]]+([[:digit:]]+)[^[:digit:]].*$/\1/p')
    (( num-- )) && $FUNCNAME $num
    builtin history -w
}

Itu builtin history bagian serta yang terakhir -wadalah karena saya memiliki variasi trik terkenal untuk berbagi sejarah di terminal dan fungsi ini akan pecah tanpa bagian-bagian itu. Mereka memastikan panggilan ke pesta nyatahistory bawaan yang (dan bukan ke pembungkus saya sendiri di sekitarnya), dan untuk menulis sejarah ke HISTFILE segera setelah entri dihapus.

Namun ini akan berfungsi sebagaimana halnya dengan konfigurasi riwayat "normal".

Anda harus memanggilnya dengan jumlah entri terakhir yang ingin Anda hapus, misalnya:

histrm 10

Akan menghapus 10 entri terakhir.

ata
sumber
1
history -d 511;history -d 511;history -d 511;history -d 511;history -d 511;history -d 511;history -d 511;history -d 511;history -d 511;history -d 511;

Brute tapi fungsional

Daddef
sumber
0
for h in $(seq $(history | tail -1 | awk '{print $1-N}')  $(history | tail -1 | awk '{print $1}') | tac); do history -d $h; done; history -d $(history | tail -1 | awk '{print $1}')

Jika Anda ingin menghapus 10 baris maka ubah saja nilai N menjadi 10.

Wasef Anwar
sumber
0

Fungsi sederhana dapat membunuh semua dengan nomor (meskipun itu kesalahan pada kesalahan)

kill_hist() {
    for i in $(echo $@ | sed -e 's/ /\n/g;' | sort -rn | sed -e 's/\n/ /;')
    do
            history -d $i;
    done
}
kill_hist `seq 511 520`
# or kill a few ranges
kill_hist `seq 1001 1010` `seq 1200 1201`
steveo'america
sumber
0

Pendek tapi manis: for i in {1..10}; do history -d $(($HISTCMD-11)); done

alkimia
sumber