How to delete history of last 10 commands in shell?

LinuxBashShellTerminal

Linux Problem Overview


Commands follows

  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

I can delete single one by history -d 511, but how to delete last 10 commands and in between 10 commands history using single command in shell?

Can we write a bash script and execute for deletion of history?

Linux Solutions


Solution 1 - Linux

Have you tried editing the history file directly:

~/.bash_history

Solution 2 - Linux

My answer is based on previous answers, but with the addition of reversing the sequence so that history items are deleted from most recent to least recent.

Get your current history (adjust the number of lines you want to see):

history | tail -n 10

This gives me something like

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"

Select the start and end positions for the items you want to delete. I'm going to delete entries 1006 to 1008.

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

This will generate history -d commands for 1006, then 1007 becomes 1006 and 1006 is deleted, then 1008 (became 1007) is now 1006 and gets deleted.

If I also wanted to delete the history delete command then it's a bit more complicated because you need to know the current max history entry.

You can get this with (there may be a better way):

history 1 | awk '{print $1}'

Putting it together you can use this to delete a range, and also delete the history delete command:

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

Wrap this all up in a function to add to your ~/.bashrc:

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

Example deleting command 4, 5 and 6 (1049-1051) and hiding the evidence:

[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

The question was actually to delete the last 10 commands from history, so if you want to save a little effort you could use another function to call the histdel function which does the calculations for you.

histdeln(){

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

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

This function takes 1 argument, the number of previous history items to delete. So to delete the last 10 commands from history just use histdeln 10.

Solution 3 - Linux

With Bash 5 you can now do a range...Hooray!:

history -d 511-520

or counting backwards 10:

history -d -10--1

Excerpt from Bash 5 Man Page:

>'history' > >Options, if supplied, have the following meanings: > > '-d OFFSET' > Delete the history entry at position OFFSET. If OFFSET is > positive, it should be specified as it appears when the > history is displayed. If OFFSET is negative, it is > interpreted as relative to one greater than the last history > position, so negative indices count back from the end of the > history, and an index of '-1' refers to the current 'history > -d' command. > > '-d START-END' > Delete the history entries between positions START and END, > inclusive. Positive and negative values for START and END are > interpreted as described above.

Here is my solution for Bash 4. It iteratively deletes a single entry or a range of history starting with lowest index.

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

delHistory 511 520

Solution 4 - Linux

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

Solution 5 - Linux

First, type: history and write down the sequence of line numbers you want to remove.

To clear lines from let's say line 1800 to 1815 write the following in terminal:

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

If you want to delete the history for the deletion command, add +1 for 1815 = 1816 and history for that sequence + the deletion command will be deleted.

For example :

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

Solution 6 - Linux

Combining answers from above:

history -w vi ~/.bash_history history -r

Solution 7 - Linux

edit:

Changed the braced iterators, good call. Also, call this function with a reverse iterator.

You can probably do something like this:

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

Where you will evoke like this:

./nameOfYourScript 563 514

Notice I haven't put any error checking in for the bounds. I'll leave that as an exercise to the reader.

see also this question

Solution 8 - Linux

Maybe will be useful for someone.
When you login to any user of any console/terminal history of your current session exists only in some "buffer" which flushes to ~/.bash_history on your logout.
So, to keep things secret you can just:
history -r && exit
and you will be logged out with all your session's (and only) history cleared ;)

Solution 9 - Linux

Not directly the requested answer, but maybe the root-cause of the question:

You can also prevent commands from even getting into the history, by prefixing them with a space character:

# This command will be in the history
echo Hello world

# This will not
 echo Hello world

Solution 10 - Linux

I used a combination of solutions shared in this thread to erase the trace in commands history. First, I verified where is saved commands history with:

echo $HISTFILE

I edited the history with:

vi <pathToFile>

After that, I flush current session history buffer with:

history -r && exit

Next time you enter to this session, the last command that you will see on command history is the last that you left on pathToFile.

Solution 11 - Linux

to delete last 10 entries (based on your example) :

history -d 511 520

Solution 12 - Linux

Short but sweet: for i in {1..10}; do history -d $(($HISTCMD-11)); done

Solution 13 - Linux

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 but functional

Solution 14 - Linux

history -c will clear all histories.

Solution 15 - Linux

I use this script to delete last 10 commands in history:

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

It uses $HISTCMD environment var to get the history index and uses that to delete last 10 entries in history.

Solution 16 - Linux

I use this (I have 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
}

The builtin history parts as well as the last -w is because I have in place a variation of the famous tricks to share history across terminals and this function would break without those parts. They ensure a call to the real bash history builtin (and not to my own wrapper around it), and to write the history to HISTFILE right after the entries were removed.

However this will work as it is with "normal" history configurations.

You should call it with the number of last entries you want to remove, for example:

histrm 10

Will remove the last 10 entries.

Solution 17 - Linux

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

If you want to delete 10 lines then just change the value of N to 10.

Solution 18 - Linux

A simple function can kill all by number (though it barfs on errors)

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`

Solution 19 - Linux

Try the following:

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

Solution 20 - Linux

the history -d arg takes a range and $HISTCMD is the max number in the history.

This function works to remove the last n entries from history (just pass in the number of history commands to remove like, eg rmhist 5) :

$ rmhist()  { history -d $(($HISTCMD - $1))-$HISTCMD ;}

Or.. Go fancy with an arg like this to remove from a point in history (inclusive) or last 'n' commands:

rmhist() { 
  case $1 in 
    --from|from) local start=$2; ;; 
    --last|last) local start=$(($HISTCMD - $2)) ;; 
    *) echo "Try rmhist --from # or rmhist --last n "; return ;; 
  esac; 
  history -d ${start}-${HISTCMD}
}

The result looks something like this:

 5778  ls /etc
 5779  ls /tmp
 5780  ls /dev
 5781  ll
 5782  cd /tmp
 5783  cd
 5784  history
(base) ~ $ rmhist --last 3
(base) ~ $ history 5
 5778  ls /etc
 5779  ls /tmp
 5780  ls /dev
 5781  ll
 5782  history 5
(base) ~ $ rmhist --from 5780
(base) ~ $ history 5
 5776  history 10
 5777  ls
 5778  ls /etc
 5779  ls /tmp
 5780  history 5

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJustin JohnView Question on Stackoverflow
Solution 1 - LinuxWheretheresaWillView Answer on Stackoverflow
Solution 2 - LinuxJGCView Answer on Stackoverflow
Solution 3 - LinuxDavid HatchView Answer on Stackoverflow
Solution 4 - LinuxBarmarView Answer on Stackoverflow
Solution 5 - LinuxGhassan ZeinView Answer on Stackoverflow
Solution 6 - LinuxBryant BernsteinView Answer on Stackoverflow
Solution 7 - LinuxTyler JandreauView Answer on Stackoverflow
Solution 8 - LinuxAlexView Answer on Stackoverflow
Solution 9 - LinuxThomas JacobView Answer on Stackoverflow
Solution 10 - LinuxM. GleriaView Answer on Stackoverflow
Solution 11 - LinuxThePhilosopherView Answer on Stackoverflow
Solution 12 - LinuxalchemyView Answer on Stackoverflow
Solution 13 - LinuxDaddefView Answer on Stackoverflow
Solution 14 - Linuxuser6280539View Answer on Stackoverflow
Solution 15 - LinuxJunaidView Answer on Stackoverflow
Solution 16 - LinuxataView Answer on Stackoverflow
Solution 17 - LinuxWasef AnwarView Answer on Stackoverflow
Solution 18 - Linuxsteveo'americaView Answer on Stackoverflow
Solution 19 - Linuxrb1234View Answer on Stackoverflow
Solution 20 - Linuxuser2711286View Answer on Stackoverflow