Come eliminare la cronologia degli ultimi 10 comandi nella shell?


131

I comandi seguono

  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

Posso eliminarne uno solo per history -d 511, ma come eliminare gli ultimi 10 comandi e tra 10 cronologia dei comandi usando il comando singolo nella shell?

Possiamo scrivere uno script bash ed eseguire per la cancellazione della storia?


18
vi $HISTFILEed elimina ciò che desideri. Utilizzare head -n -10se è necessario automatizzarlo.
Anton Kovalenko,

Questa domanda è fuori tema ? o Questo non è un posto giusto per porre questo tipo di domanda? In tal caso, dove devo porre questa domanda, intendo dove nello scambio di stack?
Justin John,

1
I comandi della shell funzionano allo stesso modo sia che tu abbia effettuato l'accesso localmente sia tramite ssh.
Barmar,

2
Unix e Linux StackExchange (unix.stackexchange.com) è probabilmente una sede migliore per questa domanda. È fuori tema qui perché non si riferisce strettamente alla programmazione.
Dan Molding

4
La programmazione di uno script di shell è la soluzione ideale a questa domanda, di conseguenza dovrebbe essere considerata correlata alla programmazione. Per non parlare del fatto che l'OP ha effettivamente richiesto uno script.
SSH Questo

Risposte:


109

Hai provato a modificare direttamente il file della cronologia:

~/.bash_history

2
@WherethereisaWill voleva uno script, non un plug and chug manuale.
Tyler Jandreau,

10
entrerà in vigore dopo il riavvio (chiusura e riapertura) del terminale
khaled_webdev l'

8
Se lo fai con vim potresti trovare la cronologia delle cancellazioni, ~/.viminfoquindi assicurati di rimuoverla!
Waltwood,

5
a volte viene conservato in memoria e qualsiasi modifica manuale non sarà mantenuta dopo il prossimo accesso ..
supereroe,

5
@FizerKhan Voglio dire che le modifiche apportate .bash_historypossono essere sovrascritte da ciò che viene tenuto in memoria. Ho trovato utile questa soluzione: superuser.com/a/384383/253543
supereroe

73

La mia risposta si basa su risposte precedenti, ma con l'aggiunta di invertire la sequenza in modo che gli elementi della cronologia vengano eliminati dal più recente al meno recente.

Ottieni la tua cronologia attuale (regola il numero di righe che vuoi vedere):

history | tail -n 10

Questo mi dà qualcosa di simile

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"

Seleziona le posizioni iniziale e finale per gli elementi che desideri eliminare. Ho intenzione di eliminare le voci da 1006 a 1008.

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

Questo genererà i history -dcomandi per 1006, quindi 1007 diventa 1006 e 1006 viene eliminato, quindi 1008 (diventato 1007) ora è 1006 e viene eliminato.

Se volessi anche eliminare il comando di eliminazione della cronologia, è un po 'più complicato perché è necessario conoscere la voce della cronologia massima corrente.

Puoi ottenerlo con (potrebbe esserci un modo migliore):

history 1 | awk '{print $1}'

Mettendolo insieme puoi usarlo per eliminare un intervallo e anche cancellare il comando di cancellazione della cronologia:

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

Riempi tutto in una funzione da aggiungere al tuo ~/.bashrc:

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

Esempio di cancellazione dei comandi 4, 5 e 6 (1049-1051) e nascondendo l'evidenza:

[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

La domanda era in realtà quella di eliminare gli ultimi 10 comandi dalla cronologia, quindi se vuoi risparmiare un piccolo sforzo potresti usare un'altra funzione per chiamare la histdelfunzione che fa i calcoli per te.

histdeln(){

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

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

Questa funzione accetta 1 argomento, il numero di elementi della cronologia precedente da eliminare. Quindi per eliminare gli ultimi 10 comandi dalla cronologia basta usare histdeln 10.


history | tail -1 | awk '{print $1}'può essere semplificato ahistory 1 | awk '{print $1}'
George Hilliard il

-bash: tac: command not foundsu Mac OSX, altrimenti questa sarebbe la risposta migliore.
Zim,

for h in $(seq 1006 1008); do history -d 1006; donefunziona su Ubuntu 16.04
Mahfuz

Breve ma dolce:for i in {1..10}; do history -d $(($HISTCMD-11)); done
alchimia,

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

3
Assicurati di usare il numero più alto per il primo argomento o eliminerai ogni altro comando. Ad esempio, quando il comando 511 viene eliminato, tutto si sposta in modo che 512 diventi il ​​nuovo 511 e 513 sia il nuovo 512. Pertanto history -d 511funziona come previsto, quindi history -d 512elimina ciò che era 513 e 512 rimane nella storia come comando 511. Spero che abbia senso .
Matteo,

5
@Matthew Non è necessario. Non sto eliminando $xogni volta attraverso il ciclo, sto eliminando $1. Quindi elimina prima 511 e 512 diventa 511. Quindi elimina di nuovo 511 e così via.
Barmar l'

@Matthew Nota che ho fatto un commento simile alla risposta di Tyler. Ho trovato la mia soluzione come soluzione per quello.
Barmar l'

hai ragione, nella mia fretta quando ho scritto questo in una sola riga nel mio prompt di bash ho usato for i in... history -d $ie ho ottenuto i risultati che ho descritto nel mio commento sopra. Usando $ 1 questo è assolutamente corretto come indicato nella risposta originale.
Matteo,

18

Innanzitutto, digitare: historye annotare la sequenza dei numeri di riga che si desidera rimuovere.

Per cancellare le righe dalla riga 1800 al 1815, scrivere quanto segue nel terminale:

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

Se si desidera eliminare la cronologia per il comando di eliminazione, aggiungere +1 per 1815 = 1816 e la cronologia per quella sequenza + il comando di eliminazione verrà eliminato.

Per esempio :

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

Ho fatto un aggiornamento ma ancora non funziona correttamente in Ubuntu 12.04 .. :( Sembra che la parte del numero di riga non
funzioni

Ho rifiutato la modifica suggerita da Binod in quanto non è un errore logico. Il codice originale di Ghassan utilizza lo stesso approccio della risposta di Barmar - che funziona. I commenti alla risposta di Barmar spiegano perché il suggerimento di sostituire 1800 con $lineelimina ogni altra riga e quindi supera l'intervallo desiderato.
Anthony Geoghegan,

18

Con Bash 5 ora puoi fare un intervallo ... Evviva !:

history -d 511-520

o contando all'indietro 10:

history -d -10--1

Estratto dalla pagina man di Bash 5 :

'storia'

Le opzioni, se fornite, hanno i seguenti significati:

'-d OFFSET' Elimina la voce della cronologia nella posizione OFFSET. Se OFFSET è positivo, deve essere specificato come appare quando viene visualizzata la cronologia. Se OFFSET è negativo, viene interpretato come relativo a uno maggiore dell'ultima posizione della cronologia, quindi gli indici negativi contano alla fine della cronologia e un indice di '-1' si riferisce all'attuale comando 'history -d'.

'-d START-END' Elimina le voci della cronologia tra le posizioni START e END, incluso. I valori positivi e negativi per START e END sono interpretati come descritto sopra.

Ecco la mia soluzione per Bash 4. Elimina in modo iterativo una singola voce o un intervallo di cronologia a partire dall'indice più basso.

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

delHistory 511 520


9

modificare:

Modificati gli iteratori rinforzati, buona chiamata. Inoltre, chiamare questa funzione con un iteratore inverso.

Probabilmente puoi fare qualcosa del genere:

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

Dove evocherai così:

./nameOfYourScript 563 514

Si noti che non ho inserito alcun errore durante il check-in per i limiti. Lo lascerò come esercizio al lettore.

vedi anche questa domanda


6
Dopo aver eliminato 510, 511 diventa 510, 512 diventa 511 e così via. Quindi questo eliminerà ogni altra riga.
Barmar

Non è possibile includere variabili nelle espansioni parentesi graffe.
Chepner,

seq 563 514non stampa nulla. Hai bisogno seq 563 -1 514. In alternativa, puoi semplicemente usare history -d $1con argomenti come514 563
anishsane il

9

Forse sarà utile per qualcuno.
Quando si accede a qualsiasi utente della cronologia console / terminale della sessione corrente esiste solo in un "buffer" che passa a ~ / .bash_history al momento del logout.
Quindi, per mantenere le cose segrete puoi solo:
history -r && exit
e verrai disconnesso con tutta la cronologia della tua sessione (e solo) cancellata;)


5

Ho usato una combinazione di soluzioni condivise in questo thread per cancellare la traccia nella cronologia dei comandi. Innanzitutto, ho verificato dove viene salvata la cronologia dei comandi con:

echo $HISTFILE

Ho modificato la cronologia con:

vi <pathToFile>

Successivamente, svuoto il buffer della cronologia della sessione corrente con:

history -r && exit

La prossima volta che entri in questa sessione, l'ultimo comando che vedrai nella cronologia dei comandi è l'ultimo che hai lasciato su pathToFile .


questo funziona per me, per la risposta di @jgc, quando accedo di nuovo al server, la cronologia è tornata di nuovo, funziona solo per quella sessione registrata
Yogeshwar Tanwar,


1

per eliminare le ultime 10 voci (in base al tuo esempio):

history -d 511 520

1
In GNU bash, versione 4.3.11 (1), questo elimina solo la prima riga dell'elenco
Gary

1

Uso questo script per cancellare gli ultimi 10 comandi nella storia:

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

Utilizza l' $HISTCMDambiente var per ottenere l'indice della cronologia e lo utilizza per eliminare le ultime 10 voci history.


1

Prova quanto segue:

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

Ciò presuppone che abbia già elencato la storia e che conosca in anticipo tutti gli ID
Markoorn il

e non può essere l'ultimo nell'elenco della cronologia, altrimenti: "posizione della cronologia fuori intervallo"
devwebcl

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

1

Lo uso (ho 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
}

Le builtin historyparti e l'ultima -wsono perché ho messo in atto una variante dei famosi trucchi per condividere la storia tra i terminali e questa funzione si spezzerebbe senza quelle parti. Assicurano una chiamata al vero bashhistory built-in (e non al mio proprio wrapper) e scrivono la cronologia su HISTFILE subito dopo che le voci sono state rimosse.

Tuttavia, funzionerà come nelle configurazioni di cronologia "normali".

Dovresti chiamarlo con il numero delle ultime voci che desideri rimuovere, ad esempio:

histrm 10

Rimuoverà le ultime 10 voci.


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;

Bruto ma funzionale


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

Se si desidera eliminare 10 righe, è sufficiente modificare il valore di N in 10.


0

Una semplice funzione può uccidere tutto per numero (anche se si blocca su errori)

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

Breve ma dolce: for i in {1..10}; do history -d $(($HISTCMD-11)); done

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.