Another nice ending is `:p` to print the command instead of executing it. I use this if I'm doing something complicated and I want to make sure it's right. Or if I'm saying `!-n:foo` with n>2. Then just up-arrow and enter to run it for real.
Here is a detail when using '!!:n' with ':p' when trying to iteratively construct a complex command. I want to emphasize the use of the up-arrow (which will show the interpolated arguments), as opposed to rewriting exactly what you wrote in the previous command, since the usage of ':p' will be interpreted by the shell as a command in itself:
$ echo a b c d
a b c d
$ echo !!:2:p
echo b
$ echo !!:2
-bash: :2: bad word specifier # there was only 1 argument in last command
However: $ echo a b c d
a b c d
$ echo !!:2:p
echo b
$
<up-arrow pressed once will give the following prompt>
$ echo bI use magic-space for that in my inputrc:
$if Bash
Space: magic-space
$endif
Basically does the same thing as :p, but after a space instead of enter.Edit: fixed formatting.
shopt -s histverify
to show the expanded command before executing it. Then just enter. I never get these right the first time.In zsh, you can hit <tab> to expand it in place before hitting <enter>.
Alt + . – use the last word of the previous command.
$ cp file.txt /some/annoyingly/deep/target/directory/other.txt
$ cd then press Alt + .
$ pwd # => /some/annoyingly/deep/target/directoryNo, that gives the last word, as you say, we want the dirname of the last word.
$ echo foo/bar
foo/bar
$ echo !$ !$:h
foo/bar fooSo you say cd M-. M-backspace M-backspace instead of cd M-.. Four keystrokes is still an improvement over shift-1 shift-4 shift-; h, which is five, plus you get to see where you're going to go before you get there.
You're incorrect. The number of M-backspace you appear to need would seem to depend on how many `little' words comprise the part that needs deleting, e.g. foo/2013-03-13 needed three M-backspace to rid me of the date and a further backspace to remove the trailing slash, which isn't insignificant to all commands, e.g. ls -ld bar/ when bar is a symlink.
In comparison. !$:h understands its task at a higher level. And thanks to key rollover, typing different characters, like !$:h, is quicker than tapping away at . until visual feedback, which may lag, tells me I've done enough.
It's true that M-backspace is occasionally less convenient, but it's usually more convenient.
Good point. I usually don't supply the file name of the second argument. Then it would be equivalent.
A sometimes handy addition to the s modifier is g, which replaces all instances of the pattern instead of just the first.
$ echo "foo foo"
foo foo
$ echo !!:s/foo/bar
echo echo "bar foo"
echo bar foo
$ echo "foo foo"
foo foo
$ echo !!:gs/foo/bar
echo echo "bar bar"
echo bar bar $ !!
runs the previous command.This is especially useful:
$ !!
$ sudo !!
Re:Unix tricks
by jschmitz28 on Thursday March 07, 2013 @12:39PM
(#5338916)
That first example is great, thanks. I run into that all the time. Up until now I've been doing this:
$ cp file.txt /some/annoyingly/deep/target/directory/other.txt
$ cd !$ (No such file or directory)
(up arrow and then backspace to directory)
I also prefer to do substitution with the :s modifier rather than ^ as suggested at the link, for consistency's sake:
Relevant Bash manual pages:http://www.gnu.org/software/bash/manual/html_node/Event-Desi...
http://www.gnu.org/software/bash/manual/html_node/Word-Desig...
http://www.gnu.org/software/bash/manual/html_node/Modifiers....