News for hackers. Stuff that matters.
Re:Unix tricks by unfletch on Thursday March 07, 2013 @11:02AM (#5338321)

    '!!:n' selects the nth argument of the last command, and '!$' the last arg
A lot of people know about "!$" (which is shorthand for !!:$), but that's just the tip of Bash's history expansion. I use these things all the time. One of my favorite keystroke savers is adding :h, the head modifier, to !$. For example:

    $ cp file.txt /some/annoyingly/deep/target/directory/other.txt
    $ cd !$:h
    $ pwd # => /some/annoyingly/deep/target/directory
Once you understand how each component works it's easier to put them together into new (to you) combinations. For example, once you know that !$ is shorthand for !!:$, it's not a huge leap to reason out that you can use !-2:$ to get the last argument to the 2nd-to-last command. Or !ls:$ for the last arg to the most recent `ls` command.

I also prefer to do substitution with the :s modifier rather than ^ as suggested at the link, for consistency's sake:

    $ echo "foo bar"
    foo bar
    $ echo !!:s/bar/baz
    foo baz
    $ echo !?bar?:s/foo/qux
    qux bar
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....

Re:Unix tricks by pjungwir on Thursday March 07, 2013 @12:52PM (#5339013)
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.
Re:Unix tricks by cawel on Thursday March 07, 2013 @07:21PM (#5341343)
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 b
Re:Unix tricks by kejadlen on Thursday March 07, 2013 @12:59PM (#5339057)
I 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.

Re:Unix tricks by absqua on Thursday March 07, 2013 @08:33PM (#5341626)

  shopt -s histverify
to show the expanded command before executing it. Then just enter. I never get these right the first time.
Re:Unix tricks by pyre on Thursday March 07, 2013 @10:46PM (#5341978)
In zsh, you can hit <tab> to expand it in place before hitting <enter>.
Re:Unix tricks by cschol on Thursday March 07, 2013 @12:49PM (#5338993)
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/directory
Re:Unix tricks by ralph on Thursday March 07, 2013 @12:55PM (#5339027)
No, 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 foo
Re:Unix tricks by kragen on Tuesday March 12, 2013 @04:12PM (#5364547)
So 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.
Re:Unix tricks by ralph on Tuesday March 12, 2013 @10:06PM (#5366352)
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.

Re:Unix tricks by kragen on Wednesday March 13, 2013 @11:23AM (#5369073)
It's true that M-backspace is occasionally less convenient, but it's usually more convenient.
Re:Unix tricks by cschol on Thursday March 07, 2013 @03:53PM (#5340168)
Good point. I usually don't supply the file name of the second argument. Then it would be equivalent.
Re:Unix tricks by sciurus on Thursday March 07, 2013 @01:02PM (#5339074)
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
Re:Unix tricks by hiroaki on Thursday March 07, 2013 @11:30PM (#5342095)

  $ !!
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)