¿Cómo eliminar el historial de los últimos 10 comandos en shell?

131

Los comandos siguen

  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

Puedo eliminar uno solo por history -d 511, pero ¿cómo eliminar los últimos 10 comandos y entre el historial de 10 comandos usando un solo comando en shell?

¿Podemos escribir un script bash y ejecutarlo para eliminar el historial?

Justin John
fuente
18
vi $HISTFILEy borra lo que quieras. Úselo head -n -10si tiene que automatizarlo.
Anton Kovalenko
¿Esta pregunta está fuera de tema ? o ¿No es el lugar adecuado para hacer este tipo de preguntas? Si es así, ¿dónde debo hacer esta pregunta, quiero decir en qué parte del intercambio de pila?
Justin John
1
Los comandos de Shell funcionan igual ya sea que haya iniciado sesión localmente o mediante ssh.
Barmar
2
Unix y Linux StackExchange (unix.stackexchange.com) es probablemente un mejor lugar para esta pregunta. Aquí está fuera de tema porque no se relaciona estrictamente con la programación.
Dan Molding
44
La programación de un script de shell es la solución ideal para esta pregunta, por lo tanto, debe considerarse relacionada con la programación. Sin mencionar el hecho de que el OP realmente solicitó específicamente un script.
SSH Este

Respuestas:

109

¿Has intentado editar el archivo de historial directamente?

~/.bash_history
WheretheresaWill
fuente
2
@WherethereisaWill OP quería un script, no un plug and chug manual.
Tyler Jandreau
10
surtirá
8
Si hace esto con vim, es posible que encuentre su historial de borrados, ¡ ~/.viminfoasí que asegúrese de eliminarlo también!
waltwood
55
a veces se guarda en la memoria y cualquier edición manual no se conservará después del próximo inicio de sesión ..
superhéroe
55
@FizerKhan Quiero decir que los cambios realizados .bash_historypueden sobrescribirse por lo que se guarda en la memoria. Esta solución me pareció útil: superuser.com/a/384383/253543
superhéroe el
73

Mi respuesta se basa en respuestas anteriores, pero con la adición de invertir la secuencia para que los elementos del historial se eliminen del más reciente al menos reciente.

Obtenga su historial actual (ajuste la cantidad de líneas que desea ver):

history | tail -n 10

Esto me da algo como

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"

Seleccione las posiciones inicial y final para los elementos que desea eliminar. Voy a eliminar las entradas 1006 a 1008.

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

Esto generará history -dcomandos para 1006, luego 1007 se convierte en 1006 y 1006 se elimina, luego 1008 (se convirtió en 1007) ahora es 1006 y se elimina.

Si también quisiera eliminar el comando de eliminación del historial, entonces es un poco más complicado porque necesita conocer la entrada actual máxima del historial.

Puede obtener esto con (puede haber una mejor manera):

history 1 | awk '{print $1}'

Al unirlo, puede usar esto para eliminar un rango y también eliminar el comando de eliminación del historial:

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

Envuelva todo esto en una función para agregar a su ~/.bashrc:

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

Ejemplo eliminando los comandos 4, 5 y 6 (1049-1051) y ocultando la evidencia:

[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 pregunta era eliminar los últimos 10 comandos del historial, por lo que si desea ahorrar un poco de esfuerzo, podría usar otra función para llamar a la histdelfunción que hace los cálculos por usted.

histdeln(){

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

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

Esta función toma 1 argumento, el número de elementos de historial anteriores para eliminar. Entonces, para eliminar los últimos 10 comandos del historial, simplemente use histdeln 10.

JGC
fuente
history | tail -1 | awk '{print $1}'se puede simplificar ahistory 1 | awk '{print $1}'
George Hilliard
-bash: tac: command not founden Mac OSX, de lo contrario, esta sería la mejor respuesta.
Zim
for h in $(seq 1006 1008); do history -d 1006; doneesto funciona en ubuntu 16.04
mahfuz
Corto pero dulce:for i in {1..10}; do history -d $(($HISTCMD-11)); done
alquimia
30
for x in `seq $1 $2`
do
  history -d $1
done
Barmar
fuente
3
Asegúrese de utilizar el número más alto para el primer argumento o eliminará cualquier otro comando. Por ejemplo, cuando se elimina el comando 511, todo cambia hacia abajo, por lo que 512 se convierte en el nuevo 511 y 513 es el nuevo 512. Por lo tanto, history -d 511funciona como se esperaba, luego history -d 512elimina lo que solía ser 513, y 512 permanece en el historial como el comando 511. Espero que tenga sentido .
Mateo
55
@Matthew Eso no es necesario. No estoy borrando $xcada vez a través del ciclo, estoy borrando $1. Por lo tanto, primero elimina 511 y 512 se convierte en 511. Luego, elimina 511 nuevamente, y así sucesivamente.
Barmar
@Matthew Observe que hice un comentario similar a la respuesta de Tyler. Se me ocurrió mi solución como una solución para eso.
Barmar
tienes razón, en mi apuro cuando escribí esto en una sola línea en mi indicador de bash que usé for i in... history -d $iy obtuve los resultados que describí en mi comentario anterior. Usando $ 1 esto es absolutamente correcto como se indica en su respuesta original.
Mateo
18

Primero, escriba: historyy escriba la secuencia de números de línea que desea eliminar.

Para borrar líneas de, digamos la línea 1800 a 1815, escriba lo siguiente en la terminal:

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

Si desea eliminar el historial del comando de eliminación, agregue +1 para 1815 = 1816 y el historial de esa secuencia + se eliminará el comando de eliminación.

Por ejemplo :

$ for line in $(seq 1800 1816) ; do history -d 1800; done
Ghassan Zein
fuente
Hice una actualización pero todavía no funciona correctamente en Ubuntu 12.04 .. :( Parece que la parte del número de línea no funciona correctamente
Binod Kalathil
Rechacé la edición sugerida de Binod ya que no es un error lógico. El código original de Ghassan usa el mismo enfoque que la respuesta de Barmar, que funciona. Los comentarios a la respuesta de Barmar explican por qué la sugerencia de reemplazar 1800 con $lineelimina cualquier otra línea y luego excede el rango deseado.
Anthony Geoghegan
18

Con Bash 5 ahora puedes hacer un rango ... ¡Hurra !:

history -d 511-520

o contando hacia atrás 10:

history -d -10--1

Extracto de la página de manual de Bash 5 :

'historia'

Las opciones, si se proporcionan, tienen los siguientes significados:

'-d OFFSET' Eliminar la entrada del historial en la posición OFFSET. Si OFFSET es positivo, debe especificarse tal como aparece cuando se muestra el historial. Si OFFSET es negativo, se interpreta como relativo a uno mayor que la última posición del historial, por lo que los índices negativos cuentan desde el final del historial, y un índice de '-1' se refiere al comando 'history -d' actual.

'-d START-END' Elimina las entradas del historial entre las posiciones START y END, inclusive. Los valores positivos y negativos para START y END se interpretan como se describe anteriormente.

Aquí está mi solución para Bash 4. Elimina iterativamente una sola entrada o un rango de historial que comienza con el índice más bajo.

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

delHistory 511 520
David Hatch
fuente
14

Combinando respuestas de arriba:

history -w vi ~/.bash_history history -r

Bryant Bernstein
fuente
9

editar:

Cambió los iteradores arriostrados, buena decisión. Además, llame a esta función con un iterador inverso.

Probablemente puedas hacer algo como esto:

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

Donde evocarás así:

./nameOfYourScript 563 514

Tenga en cuenta que no he colocado ningún error al registrar los límites. Lo dejaré como ejercicio para el lector.

ver también esta pregunta

Tyler Jandreau
fuente
66
Después de eliminar 510, 511 se convierte en 510, 512 se convierte en 511, y así sucesivamente. Así que esto eliminará cualquier otra línea.
Barmar
No puede incluir variables en expansiones de llaves.
chepner
seq 563 514No imprimirá nada. Es necesario seq 563 -1 514. Alternativamente, puede usar simplemente history -d $1con argumentos como514 563
anishsane
9

Quizás sea útil para alguien.
Cuando inicia sesión en cualquier usuario de cualquier consola / terminal, el historial de su sesión actual solo existe en algún "búfer" que se vacía a ~ / .bash_history en su cierre de sesión.
Entonces, para mantener las cosas en secreto, puede simplemente:
history -r && exit
y se cerrará la sesión con todo el historial de su sesión (y solo) borrado;)

Alex
fuente
5

Utilicé una combinación de soluciones compartidas en este hilo para borrar el rastro en el historial de comandos. Primero, verifiqué dónde se guarda el historial de comandos con:

echo $HISTFILE

Edité la historia con:

vi <pathToFile>

Después de eso, enjuago el búfer de historial de sesión actual con:

history -r && exit

La próxima vez que ingrese a esta sesión, el último comando que verá en el historial de comandos es el último que dejó en pathToFile .

M. Gleria
fuente
esto funciona para mí, para la respuesta de @jgc, cuando vuelvo a iniciar sesión en el servidor, el historial vuelve a funcionar, solo funciona para esa sesión iniciada
Yogeshwar Tanwar
1

history -c borrará todas las historias.

usuario6280539
fuente
1

para eliminar las últimas 10 entradas (según su ejemplo):

history -d 511 520
El filósofo
fuente
1
En GNU bash, versión 4.3.11 (1), esto solo elimina la primera línea de la lista
Gary
1

Utilizo este script para eliminar los últimos 10 comandos en la historia:

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

Utiliza el $HISTCMDentorno var para obtener el índice del historial y lo utiliza para eliminar las últimas 10 entradas history.

Junaid
fuente
1

Intenta lo siguiente:

for i in {511..520}; do history -d $i; echo "history -d $i"; done
rb1234
fuente
Eso supone que ya ha enumerado el historial y conoce todas las identificaciones de antemano
Markoorn
y no puede ser el último en la lista de historial, de lo contrario: "posición de historial fuera de rango"
devwebcl
que debe ser:for i in {511..520}; do history -d $i; echo "history -d 511"; done
devwebcl
1

Yo uso esto (tengo 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
}

Las builtin historypartes, así como la última, -wse deben a que tengo una variación de los famosos trucos para compartir la historia entre terminales y esta función se rompería sin esas partes. Aseguran una llamada al bash real historyincorporado (y no a mi propio contenedor), y a escribir el historial en HISTFILE justo después de que se eliminen las entradas.

Sin embargo, esto funcionará tal como está con las configuraciones de historial "normales".

Debe llamarlo con el número de las últimas entradas que desea eliminar, por ejemplo:

histrm 10

Eliminará las últimas 10 entradas.

ata
fuente
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 pero funcional

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

Si desea eliminar 10 líneas, simplemente cambie el valor de N a 10.

Wasef Anwar
fuente
0

Una función simple puede matar a todos por número (aunque molesta los errores)

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
fuente
0

Corto pero dulce: for i in {1..10}; do history -d $(($HISTCMD-11)); done

alquimia
fuente