Bash / zsh : Using the history expansion

One of the features of bash I’ve too long overlooked is its history expansion. In this post I’ll show a few examples to get a grip at it.

Recall a previous line

  • Recall the last line
    kattoo@roadrunner ~ $ date
    Sun Mar 28 18:35:12 CEST 2010
    kattoo@roadrunner ~ $ !!
    date
    Sun Mar 28 18:35:13 CEST 2010
    kattoo@roadrunner ~ $ 
    
  • Recall the n-th last line :
    kattoo@roadrunner ~ $ echo 1
    1
    kattoo@roadrunner ~ $ echo 2
    2
    kattoo@roadrunner ~ $ echo 3
    3
    kattoo@roadrunner ~ $ !-3
    echo 1
    1
    kattoo@roadrunner ~ $ 
    
  • Recall the n-th line of the history
    kattoo@roadrunner ~ $ history
    [...]
      533  date
      534  date
      535  echo 1
      536  echo 2
      537  echo 3
      538  echo 1
      539  history
    kattoo@roadrunner ~ $ !536
    echo 2
    2
    kattoo@roadrunner ~ $ 
    

Re-using previous command line arguments

  • Re-use all the arguments of the previous command
    kattoo@roadrunner ~ $ touch test-file.txt
    kattoo@roadrunner ~ $ scp !* remote:/tmp
    scp test-file.txt spaghetti:/tmp
    test-file.txt                                             100%    0     0.0KB/s   00:00    
    kattoo@roadrunner ~ $
    
  • Re-use the m-th argument from the n-th previous command line
    kattoo@roadrunner ~ $ echo 1 2 3
    1 2 3
    kattoo@roadrunner ~ $ echo !-1:2
    echo 2
    2
    kattoo@roadrunner ~ $
    
  • Re-run the previous command changing occurrences of X by Y
    kattoo@roadrunner ~ $ echo test
    test
    kattoo@roadrunner ~ $ ^test^replaced
    echo replaced
    replaced
    kattoo@roadrunner ~ $ 
    

That’s about it… those are what I consider to be the most useful history expansion features of bash.

Do you have any other you find especially useful ? Share them in the comments !

One thought on “Bash / zsh : Using the history expansion”

  1. Your example is less strict than it could be. I’d recommend using $_ instead of !*. This would make it compatible with something like,

    $ some_filter input_file -o output_file
    $ scp $_ remote:/tmp

    Whereas ‘scp !* remote:/tmp’ would expand to ‘scp input_file -o output_file remote:/tmp’.

Comments are closed.