Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

We all know that !! can repeat the last command you do in bash.

But sometimes we need to do some operation like

$ python test.py
$ vim test.py

$ python test.py # here is where I need to repeat the second proximate bash command

I can use up-arrow key to do that, but that requires me to move my right hand away to an uncomfortable position. So I'm wondering if there is a command which like !! can help me to realize my purpose?

share|improve this question
    
Use Ctrl+P in emacs mode (default), or k in vi-mode if you don't want to reach for the up key. –  Stéphane Chazelas Aug 20 at 9:48
    
I’d actually write both commands in one line like vim test.py && python test.py to avoid fiddling with multiple commands in history, but you can simply bind "\ep": previous-history in your ~/.inputrc so you could press Alt+p instead of up key. –  tijagi Aug 20 at 13:00

2 Answers 2

up vote 4 down vote accepted

You can use !-2:

$ echo foo
foo
$ echo bar
bar
$ !-2
echo foo
foo

That may not help with your right-hand situation.

You can also use !string history searching for this sort of case:

$ python test.py
$ vim test.py
$ !py
python test.py # Printed, then run

This may be more convenient to use. It will run:

the most recent command preceding the current position in the history list starting with string.

Even just !p would work. You can use !?string to search the whole command line, rather than just the start.

share|improve this answer
    
It's much better! since arrow keys needs to move your entire wrist, and !-2 only requires finger movements, excellent, Michael. Wow, just read the second part, it's out of my expectation. You are a magician! –  Zen Aug 20 at 8:38
!-2

More fun is available. Say you want to keep operating on a file (as above, where you're using test.py, repeatedly):

cp foo.py thing.py
edit $_
python $_
!-2
^thing^foo
  • Copy an existing file to thing.py
  • Edit (vim, emacs - though why you'd be using a command line if you were running Emacs-OS, I have no idea) thing.py - the last word in the previous command line
  • python thing.py
  • Edit thing.py
  • Edit foo.py

History manipulation is such fun. Try man history. Note that the quest to re-use history can result in typing far more than the command itself would. The final command substitution, where I replace thing.py by foo.py is one such example. Fewer characters to just type in the command and name. :)

The history substitution is also why you get strange messages when you try:

$ echo "This is a disaster!"
-bash: !": event not found

The exclamation mark is being consumed as a history reference, and it can't find a previous command with a double quote.

share|improve this answer
    
+1 for the last keyword replace command in the second code block of your answer. –  Zen Aug 20 at 9:28
    
By the way, If I got echo 'xxx', how do I substitute each 'x' into 'y'? –  Zen Aug 20 at 9:32
    
Substituting a string for another string? Just that? !!:1gs/x/y/ –  JezC Aug 20 at 9:44
    
Though personally, I'd be looking at $(echo !! | sed -e s/x/y/g) –  JezC Aug 20 at 9:51
    
using sed would be too clumsy, can I add some parameter or symbol in ^x^y to do that job? –  Zen Aug 20 at 9:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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