4

I have two scripts that often need to be run with the same parameter:

$ populate.ksh 9241 && check.ksh 9241

When I need to change the parameter (9241 in this example), I can go back and edit the line in history. But since I need to change the number in two places, I sometimes make a typo. I'd like to be able to change the parameter just once to change it in both places.

4 Answers 4

10

In bash:

!!:gs/9241/9243/

Yes, it uses gs///, not s///g. :-)

(zigdon's answer uses the last command starting with pop, such as populate.sh. My answer uses the last command, full stop. Choose which works for you.)

Sign up to request clarification or add additional context in comments.

3 Comments

I don't know if it's true, but this feature seems to use more keystrokes than just editing the command line. I used to be in love with the bang notation for recalling history, but for some reason I don't use it anymore. Hopefully your answer will help others, however. ;-)
Think about a complex command with lots of logical operators and pipes, this one will be a life saver :)
The 'g' is not working for me. It only replaces the first occurrence of 9241. Is there a config option in bash that needs to be set?
5

You can also use the history substitution feature:

!pop:gs/9241/1234

Like so:

$ populate.ksh 9241 && check.ksh 9241
...
$ !pop:gs/9241/1234
populate.ksh 1234 && check.ksh 1234
...

Comments

2

Correct answers have already been given, but for a more general understanding read the manpage with special attention to "History Expansion" and the associated shell variables (such as "HISTCONTROL", "histchars", etc.). BTW-- Your pager's search function is very useful when reading man bash

Comments

1

One solution is to simply create a wrapper script (populate_check.ksh) that calls the scripts in turn:

r=$1
populate.ksh $r && check.ksh $r

Or for multiple parameters:

for r; do
   populate.ksh $r && check.ksh $r
done

For tasks that are more transient, you can also parametrize the command so that it's easier to edit in history:

$ r=9241; populate.ksh $r && check.ksh $r

Or to do several at once:

$ for r in 9241 9242; do populate.ksh $r && check.ksh $r; done

4 Comments

Don't say "for r in $*"; prefer to say "for r" instead. The latter allows you to specify arguments with spaces or other IFS characters.
For lurkers and archives: for r is equivalent to for r in "$@", for those unfortunate enough to use a shell not supporting the shorter form.
Excellent! Once again, posting questions I know the answer to pays off. Thanks.
you can also define a shell function and put it in $SHELLrc file, better than writing a yet another script file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.