65

The history command lists out all the history for the current session. Like:

1 ls 
2 cd /root
3 mkdir something
4 cd something
5 touch afile
6 ls
7 cd ..
8 rm something/afile
9 cd ..
10 ls
11 history

In order to search items of interest, I can pipe history with grep like

history | grep ls
1 ls
6 ls
10 ls

I can also view last 3 commands like:

history 3
11 history
12 history | grep ls
13 history 3

But how do I get a specific range of history? For example something like:

history range 4 7
4 cd something
5 touch afile
6 ls
7 cd ..
2
  • You could list the last x commands then pipe to head.
    – Bratchley
    Jun 22, 2016 at 3:52
  • @Bratchley: For that I'd have to know how many last commands to go to. Consider this, my history | grep something shows results of commands numbered 123 234 345 in history and I may not know the number of last command executed (history in this case). My last command could be numbered 400, 500 or whatever. So first I have to check that number, figure out the difference, list the last x commands and then pipe to head Jun 22, 2016 at 3:59

5 Answers 5

100

Instead of history, you can use fc, which allow you select range:

fc -l 4 7
2
  • 7
    It even accepts negative numbers to count from the end, like fc -l -16 -10. Jun 22, 2016 at 8:39
  • 2
    hmm, wonder why we need a whole new command instead of just arguments to the actual command...
    – Ringo
    May 10, 2019 at 1:56
15

If you must use history command, pipe it through sed or awk:

history | sed -n '10,20p'

history | awk 'NR >= 10 && NR <= 20'

Otherwise cuonglm's answer is better option.

3
  • @questionto42standswithUkraine I've deleted my comment which didn't serve much purpose, but the 15 and 25 in this pipeline should be preceded by a dash. Since they aren't, tail and head assume they are files they should be reading from, hence the error message
    – Aaron
    Apr 5 at 17:31
  • 2
    @questionto42standswithUkraine I'm honestly not convinced that head+tail has any advantage over sed -n "${start},${end}p". If you are, I invite you to add an answer. Otherwise I'll think about adding one but I won't promise anything
    – Aaron
    Apr 5 at 17:55
  • @questionto42standswithUkraine I don't want to post an answer, please stop trying to convince me. Just post the damn answer yourself
    – Aaron
    Apr 15 at 9:04
2

Using history with a grep on the line numbers around the command I'm looking for works best for me.

For instance I'm looking for what I did around ping mybox, more or less 20 lines.

$ history | grep "ping mybox" 20325 ping mybox

That's line 20325 so I just have to grep the lines starting by a number in the [20320..20339] range.

$ history | grep ^203[2-3][0-9]

1
  • 1
    (1) You say “more or less 20”, but your example shows −5 and +14.   (2) This doesn’t work for me, because history numbers seem to have leading spaces. Oct 6, 2017 at 10:06
0

Here is an answer that uses the history command with a parameter.

Credits go to this user who did not want to make his now deleted comment an answer. I am taking over since I think that the now deleted comment should be an answer on its own.

Most used

history | tail -5 

gives you the last 5 lines. Which should be all you need in everyday programming, change to the lines you need of course. I am using this by heart from the start, easy to remember.

Further

history | head -5 

gives you the first 5 lines,

history | tail -10 | head -5

gives you the second last 5 lines

history | head -10 | tail -5 

the lines 7 to 11. You need

history | head -8 | tail -5

to get the second 5 lines, meaning 6 to 10, strange, but no big issue to always add +2 on the head in such cases and you do not need the head of the history anyway or a chosen slice of it if you just want to shrink the full history down to the normally younger commands.

-1

Assuming you want the range 4 to 7:

history  4 | head -n 3

In this method, you can generally get history from n to m with:

history n | head -n m-n

Note that the head command is literally head -n followed by a number, as shown in the first command.

1
  • 2
    (1) No, history 4 gives the most recent four commands, not everything starting at command #4.  (2) No, to get thing # n through thing # m, you need to grab m − n+ 1 things. … … … … … … Besides, all of this has been covered already. May 16 at 17:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.