Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get second-to-last argument from previous bash command? (in an interactive bash shell)

How can I easily get the second-to-last (penultimate) word/argument from the previous command in a bash interactive shell? I often run commands in the background, and I would like to get the file that was specified before the &, e.g.,

  % echo foo > /tmp/foo &
  % cat !$
  % &

In the example above, !$ gives the last word, &. But I want the second-to-the-last argument, /tmp/foo



Note that it is possible to use word designators with a range like !-1:3, but this is impractical for a command with a large number of words where it's not quickly obvious how many words there are, e.g.,

% (set -x; date; pwd; git status; git diff;  git log | tail -30; date; args=--verbose time make test; date) >& /tmp/log/make.test.20150122-Thu-0834 &
% echo !-1:30
/tmp/log/make.test.20150122-Thu-0834

The example above works, but you have to count and know that the word you want is the 30th word, which is time-consuming and error-prone.

Is there an easy way to get the second-to-last (penultimate) word?

UPDATE: Note that I'm looking for something to type on the command line (e.g., a history expansion, like the !! event designator, or the $ word designator), as opposed to using readline key bindings (e.g., the esc key).

(Note that this question refers to the arguments of a previous command in an interactive shell, and not to arguments passed to a shell script from the command-line, as some answers and comments here are referring to.)

like image 838
Rob Bednark Avatar asked Jan 21 '15 00:01

Rob Bednark


People also ask

Which bash shortcut or command copies the last argument of previous commands?

In the command-line, you can press alt + . or esc - . It cycles through the last argument of your previous commands.

Which history shortcut can you use to reference the previous command arguments?

To insert previous arguments: Alt + # + . : insert #nth last argument from last command.

How do I pass multiple arguments in bash?

You can pass more than one argument to your bash script. In general, here is the syntax of passing multiple arguments to any bash script: script.sh arg1 arg2 arg3 … The second argument will be referenced by the $2 variable, the third argument is referenced by $3 , .. etc.

What is $@ in bash?

bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.


2 Answers

Interactively, you can get the second to last argument of the previous command line with esc - 1 esc . with the default bindings.

More generally, the sequence esc . gets the final token from the previous command line, and you can pass it a numeric argument to specify a different one (for example, esc 1 esc . gets the first argument, and esc 0 esc . gets the command itself).

esc is one of the keybindings for Meta; on many modern keyboards, you can use Alt as Meta as well (you press it at the same time, not as a prefix modifier). I prefer esc as meta because when my muscle memory learned these things, we didn't have no (reliable, consistent) Alt key, and it's still portable all the way to VT100 and Sun keyboards; and at least on my current keyboard (Mac OSX Yosemite) e.g. alt-- does something else than specify a negative numeric argument.

From a previous compound command like this

echo moo; echo bar

the sequence esc 2 esc . gets the semicolon, because that's the second token.

I'm sure there is a way with ! history expansion as well, but I vastly prefer to see what I'm doing. This mechanism brings you the text you want to refer to into your current command line, so you can edit it if you like as well.

like image 137
tripleee Avatar answered Nov 01 '22 19:11

tripleee


Use this to run a command using the 3rd argument of the last command in history:

echo foo > /tmp/foo &
cat !-1:3
like image 29
Gary_W Avatar answered Nov 01 '22 17:11

Gary_W