71

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

110

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
  • 3
    hmm, wonder why we need a whole new command instead of just arguments to the actual command...
    – Ringo
    May 10, 2019 at 1:56
17

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, 2022 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, 2022 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, 2022 at 9:04
3

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
1

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, 2022 at 17:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .