Kabuktaki son 10 komutun geçmişi nasıl silinir?


131

Komutlar takip eder

  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

Tek bir history -d 511komutu silebilirim, ancak son 10 komutu ve 10 komut arasında geçmişini tek bir komut kullanarak kabukta nasıl silebilirim?

Tarihin silinmesi için bir bash betiği yazıp çalıştırabilir miyiz?


18
vi $HISTFILEve istediğinizi silin. head -n -10Otomatikleştirmeniz gerekiyorsa kullanın .
Anton Kovalenko

Bu soru konu dışı mı? veya Burası bu tür soruları sormak için doğru bir yer değil mi? Eğer öyleyse, bu soruyu nereye sormalıyım, yani yığın değişiminde nerede?
Justin John

1
Kabuk komutları, yerel olarak veya ssh aracılığıyla oturum açsanız da aynı şekilde çalışır.
Barmar

2
Unix ve Linux StackExchange (unix.stackexchange.com) muhtemelen bu soru için daha iyi bir yerdir. Burada konu dışıdır çünkü programlamayla kesinlikle ilgili değildir.
Dan Molding

4
Bir kabuk betiğini programlamak, bu soru için ideal bir çözümdür, dolayısıyla programlamayla ilgili olarak düşünülmelidir. OP'nin aslında bir senaryo istediği gerçeğinden bahsetmiyorum bile.
SSH Bu

Yanıtlar:


109

Geçmiş dosyasını doğrudan düzenlemeyi denediniz mi:

~/.bash_history

2
@WherethereisaWill OP bir komut dosyası istedi, manuel bir fiş ve chug değil.
Tyler Jandreau

10
terminali yeniden başlattıktan (kapatıp yeniden açtıktan) sonra yürürlüğe girecek
khaled_webdev

8
Bunu vim ile yaparsanız, silme geçmişinizi bulabilirsiniz, ~/.viminfobu yüzden onu da kaldırdığınızdan emin olun!
waltwood

5
bazen hafızada tutulur ve herhangi bir manuel düzenleme bir sonraki girişten sonra devam etmez ..
superhero

5
@FizerKhan Demek istediğim, .bash_historybellekte tutulanlar tarafından yapılan değişikliklerin üzerine yazılabilir. Bu çözümü faydalı buldum: superuser.com/a/384383/253543
superhero

73

Cevabım önceki cevaplara dayanıyor, ancak sırayı tersine çevirmenin yanı sıra, geçmiş öğeleri en yeniden en yeniye doğru silinecek.

Mevcut geçmişinizi alın (görmek istediğiniz satır sayısını ayarlayın):

history | tail -n 10

Bu bana şöyle bir şey veriyor

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"

Silmek istediğiniz öğeler için başlangıç ​​ve bitiş konumlarını seçin. 1006'dan 1008'e kadar olan girişleri sileceğim.

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

Bu, history -d1006 için komutlar üretir , sonra 1007, 1006 olur ve 1006 silinir, sonra 1008 (1007 oldu) şimdi 1006 olur ve silinir.

Geçmiş silme komutunu da silmek istersem, bu biraz daha karmaşık çünkü mevcut maksimum geçmiş girişini bilmeniz gerekir.

Bunu şununla elde edebilirsiniz (daha iyi bir yol olabilir):

history 1 | awk '{print $1}'

Bir araya getirerek, bir aralığı silmek için bunu kullanabilir ve ayrıca geçmiş silme komutunu da silebilirsiniz:

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

Bunları, aşağıdakilerinize eklemek için bir işlevle özetleyin ~/.bashrc:

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

Örnek 4, 5 ve 6 (1049-1051) komutunu silme ve kanıtları saklama:

[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

Asıl soru, son 10 komutu geçmişten silmekti, bu nedenle biraz çaba harcamak istiyorsanız histdel, hesaplamaları sizin için yapan işlevi çağırmak için başka bir işlevi kullanabilirsiniz .

histdeln(){

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

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

Bu işlev, silinecek önceki geçmiş öğelerinin sayısı olan 1 argüman alır. Bu yüzden son 10 komutu geçmişten silmek için kullanın histdeln 10.


history | tail -1 | awk '{print $1}'basitleştirilebilirhistory 1 | awk '{print $1}'
George Hilliard

-bash: tac: command not foundMac OSX'te, aksi takdirde bu en iyi cevap olacaktır.
Zim

for h in $(seq 1006 1008); do history -d 1006; donebu ubuntu 16.04'te çalışır
mahfuz

Kısa ama tatlı:for i in {1..10}; do history -d $(($HISTCMD-11)); done
simya

30
for x in `seq $1 $2`
do
  history -d $1
done

3
İlk bağımsız değişken için daha yüksek sayıyı kullandığınızdan emin olun, yoksa diğer tüm komutları silersiniz. Örneğin, komut 511 silindiğinde, her şey aşağı kayar, böylece 512, yeni 511 olur ve 513, yeni 512 olur. Bu nedenle history -d 511, beklendiği gibi çalışır, sonra history -d 512513 olanı siler ve 512, 511 komutu olarak geçmişte kalır. .
Matthew

5
@Matthew Bu gerekli değil. Ben silme değilim $xdöngü içinde her zaman, ben siliyorum $1. Yani önce 511'i siler ve 512, 511 olur. Sonra tekrar 511'i siler ve bu böyle devam eder.
Barmar

@Matthew Tyler'ın cevabına benzer bir yorum yaptığımı fark ettim. Çözümümü bunun için bir çözüm olarak buldum.
Barmar

haklısın, bunu bash istemimde tek satıra yazarken acelemle kullandım for i in... ve history -d $iyukarıdaki yorumumda anlattığım sonuçları aldım. $ 1 kullanmak, orijinal cevabınızda belirtildiği gibi kesinlikle doğrudur.
Matthew

19

Bash 5 ile artık bir dizi yapabilirsiniz ... Yaşasın !:

history -d 511-520

veya geriye doğru sayarsak 10:

history -d -10--1

Bash 5 Man Sayfasından Alıntı :

'Tarih'

Sağlanan seçenekler aşağıdaki anlamlara gelir:

'-d OFFSET' OFFSET konumundaki geçmiş girişini silin. OFFSET pozitifse, geçmiş görüntülendiğinde göründüğü gibi belirtilmelidir. OFFSET negatifse, son geçmiş konumundan daha büyük olana göre yorumlanır, bu nedenle negatif endeksler geçmişin sonundan geriye doğru sayılır ve '-1' dizini geçerli 'geçmiş -d' komutuna karşılık gelir.

'-d BAŞLANGIÇ-BİTİŞ' BAŞLANGIÇ ve BİTİŞ konumları arasındaki geçmiş girişlerini, dahil silin. START ve END için pozitif ve negatif değerler yukarıda açıklandığı gibi yorumlanır.

İşte Bash 4 için çözümüm. Tek bir girişi veya en düşük indeksle başlayan bir geçmiş aralığını yinelemeli olarak siler.

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

delHistory 511 520

18

İlk olarak şunu yazın: history ve kaldırmak istediğiniz satır numaraları sırasını yazın.

Diyelim ki 1800'den 1815'e kadar olan satırları temizlemek için terminalde aşağıdakileri yazın:

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

Silme komutunun geçmişini silmek isterseniz, 1815 = 1816 için +1 ekleyin ve bu sekans için geçmiş + silme komutu silinecektir.

Örneğin :

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

Ubuntu
12.04'te

Mantıksal bir hata olmadığı için Binod'un önerilen düzenlemesini reddettim. Ghassan'ın orijinal kodu, Barmar'ın cevabıyla aynı yaklaşımı kullanıyor - işe yarıyor. Barmar'ın cevabına yapılan yorumlar, 1800'ü değiştirme önerisinin neden her iki satırı$line sildiğini ve ardından istenen aralığı aştığını açıklıyor .
Anthony Geoghegan


9

Düzenle:

Hazırlanan yineleyicileri değiştirdik, iyi karar. Ayrıca, bu işlevi bir ters yineleyici ile çağırın.

Muhtemelen şöyle bir şey yapabilirsiniz:

#!/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

Böyle uyandıracağınız yer:

./nameOfYourScript 563 514

Sınırları kontrol etmek için herhangi bir hata koymadım. Bunu bir alıştırma olarak okuyucuya bırakacağım.

ayrıca bu soruya bakın


6
510'u sildikten sonra 511, 510, 512 ise 511 olur ve bu böyle devam eder. Bu, diğer her satırı silecektir.
Barmar

Değişkenleri küme ayracı genişletmelerine dahil edemezsiniz.
chepner

seq 563 514hiçbir şey yazdırmayacak. İhtiyacın var seq 563 -1 514. Alternatif olarak, basitçe kullanabilirsiniz history -d $1olarak argümanlarla514 563
anishsane

9

Belki birisi için yararlı olur.
Herhangi bir konsolun / terminalin herhangi bir kullanıcısında oturum açtığınızda, geçerli oturumunuzun yalnızca bazı "arabellekte" bulunur ve bu, çıkışınızda ~ / .bash_history'ye boşaltılır.
Yani, işleri gizli tutmak için şunları yapabilirsiniz:
history -r && exit
ve oturumunuzun tüm (ve yalnızca) geçmişi temizlenmiş olarak çıkış yaparsınız;)


5

Komut geçmişindeki izi silmek için bu iş parçacığında paylaşılan çözümlerin bir kombinasyonunu kullandım. İlk olarak, komut geçmişinin nereye kaydedildiğini doğruladım:

echo $HISTFILE

Geçmişi şu şekilde düzenledim:

vi <pathToFile>

Bundan sonra, mevcut oturum geçmişi tamponunu şu şekilde temizlerim:

history -r && exit

Bu oturuma bir dahaki girişinizde , komut geçmişinde göreceğiniz son komut, pathToFile'da bıraktığınız son komuttur .


Bu benim için işe yarıyor, @jgc'den gelen yanıt için, sunucuya tekrar giriş yaptığımda, geçmiş tekrar geri geldi, yalnızca oturum açmış oturum için çalışıyor
Yogeshwar Tanwar


1

son 10 girişi silmek için (örneğinize göre):

history -d 511 520

1
GNU bash sürüm 4.3.11 (1) 'de bu yalnızca listedeki ilk satırı siler
Gary

1

Geçmişteki son 10 komutu silmek için bu komut dosyasını kullanıyorum:

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

O kullanır $HISTCMDson 10 girişleri silmek için tarih indeksini ve kullanımlarını almak için çevre Var history.


1

Takip etmeyi dene:

for i in {511..520}; do history -d $i; echo "history -d $i"; done

Geçmişi zaten listelediğini ve tüm kimlikleri önceden bildiğini varsayar
Markoorn

ve geçmiş listesindeki en son olamaz, aksi takdirde: "geçmiş konumu aralık dışı"
devwebcl

şu olmalıdır:for i in {511..520}; do history -d $i; echo "history -d 511"; done
devwebcl

1

Bunu kullanıyorum (bende 4 bash var):

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

builtin historyParçalar ve de son -wben yerde ünlü bir varyasyonunu var çünkü terminalleri arasında pay tarihe hile ve bu fonksiyon bu parçaların olmadan kırardı. Gerçek bash için bir çağrı sağlarlarhistory yerleşikine (kendi sarmalayıcıma değil) ve girdiler kaldırıldıktan hemen sonra geçmişi HISTFILE'a yazmak sağlarlar.

Ancak bu, "normal" geçmiş yapılandırmalarında olduğu gibi çalışacaktır.

Silmek istediğiniz son girişlerin numarasıyla aramalısınız, örneğin:

histrm 10

Son 10 girişi kaldıracak.


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;

Kaba ama işlevsel


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}')

10 satırı silmek istiyorsanız, N'nin değerini 10 olarak değiştirin.


0

Basit bir işlev, hepsini sayıya göre öldürebilir (hatalara engel olsa da)

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`

0

Kısa ama tatlı: for i in {1..10}; do history -d $(($HISTCMD-11)); done

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.