Bash reference previous arguments on one line

I seem to remember that bash had a shortcut to refer to something on the same line. I know and use !$ , !! and friends regularly. I remember reading the opportunity to do something like the following:

 mkdir tmp && cd !_ 

where !_ represents a combination that I don’t remember. (The goal of the above is to make the directory and immediately cd into it upon successful completion). Google only provides repositories from the same 2 referenced tables that do not have this combination.

I am currently using a less effective

 mkdir tmp cd !$ 

who does the job, but not the way I want to do it.

Does anyone know this elusive shortcut?

In case that matters, I use zsh with oh-my-zsh , not vanilla bash .

+6
source share
4 answers
 mkdir tmp && cd "$_" 

- this is what you are looking for, I believe (you can strip double quotes if you are sure that quoting is not required).

$_ expands differently in different contexts, but it matters here (from man bash , v3.2.51):

expands to the last argument of the previous command after expansion.

Background

Note: the next section discusses bash , but apparently it also applies to zsh .

$_ is the so-called special parameter that you will find among others (without the $ prefix) in the Special Parameters man bash section:

  • It works both in interactive shells and in scripts.
  • It works at the level of an individual team, and not at the line level.

Unlike ! -described tokens (for example,! !$ to call the last token of the last line) refer to the extension of the [command] history (section HISTORY EXPANSION of man bash ):

  • By default, they only work in interactive shells, but they can be changed using set -o history and set -o histexpand (thanks, @chepner).
  • Work at the line level (more precisely: everything that was presented with a single press of the Enter key, regardless of how many separate commands or lines it contained).
+6
source

!# still refers to the command line, and you can extract certain words from it:

 mkdir tmp && cd !#:1 

The same syntax works in zsh .

+5
source

How about this:

 mkdir foo; cd $_ 

It works for me.

+1
source

(Old news, but in case someone lands here looking for it, how I did it)


OP seems to be looking for syntax !#[X][-Y] zsh

where X and Y are the indices for shell words in the story event for the current row

It is assumed that X and Y refer to the beginning or end of the line - respectively - when lowering

(keep in mind that the end of the line in this context is actually a call event !#[X][-Y] per line)

this gives us the following options:

  • !# current line to !#

  • !#-Y current line up Y th word

  • !#X X Only one word

  • !#XY words X through Y

  • !#X- from the X word, bye !#X-

in a direct answer to an example:

 mkdir tmp && cd !#2 

or, taking another step:

 alias mktmpd='mkdir -p tmp /tmp/${PWD:t}; cd ${(@)${~:-${=^:-!#2-3}(N/)}[1]}; pwd; ls' 

the path /tmp/${PWD:t} will also be created and act as an alternative to cd if for any reason ./tmp cannot be created (which could fail)

this assumes the user can mkdir in /tmp and wants some useless paths to be generated (and left untouched) when ./tmp perfectly used and actually selected

there is a potential problem when /tmp/${PWD:t} already exists and its contents are not connected or broken, therefore pwd; ls pwd; ls

aliasing helps with cases such as somecommand; mktmpd somecommand; mktmpd , where usually #! 2-3 will no longer refer to the corresponding parameters tmp /tmp/${PWD:t}

Note, however, that I strongly do not advocate this use case as particularly useful (or even its suitability as an example, actually), but I wanted to point out the peculiarity of the alias, since I had not yet seen its mention elsewhere)

0
source

All Articles