Domanda

I seem to remember that bash had a bang-shortcut for referring to something in the same line. I know and use !$, !! and friends regularly. I recall reading being able to do something like the following:

mkdir tmp && cd !_

where !_ represents the combination I can't remember. (The goal of the above is to make a directory and immediately cd into it upon success.) Google only yields reposts of the same 2 reference tables which don't have this combination.

Right now I'm using the less-efficient

mkdir tmp
cd !$

which gets the job done but not the way I want to do it.

Does anyone know this elusive shortcut?

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

È stato utile?

Soluzione

mkdir tmp && cd "$_"

is what you're looking for, I believe (you can drop the double quotes if you're sure that quoting is not needed).

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

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

Background:

Note: the following discusses bash, but it seems to apply to zsh in principle as well.

$_ is a so-called special parameter, which you'll find listed among others (without the $ prefix) in the Special Parameters section of man bash:

  • Works both in interactive shells and in scripts.
  • Works at the individual command level, not at the line level.

By contrast, !-prefixed tokens (such as !$ to recall the most recent line's last token) relate to the shell's [command] history expansion (section HISTORY EXPANSION of man bash):

  • By default they work only in interactive shells, but that can be changed with set -o history and set -o histexpand (thanks, @chepner)).
  • Work at the line level (more accurately: everything that was submitted with one Enter keystroke, no matter how many individual commands or lines it comprised).

Altri suggerimenti

!# refers to the command line so far, and you can extract specific words from it:

mkdir tmp && cd !#:1

The same syntax works in zsh as well.

What about this:

mkdir foo; cd $_

Works for me.

(Old news, but in case someone else lands here looking for this, like I just did)


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

where X and Y are indexes for shell words in history event for current line

X and Y are assumed to refer to the start or end of line - respectively - when omitted

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

this gives us the following variants:

  • !# current line up to !#

  • !#-Y current line up the Y-th word

  • !#X X-th word only

  • !#X-Y words X through Y

  • !#X- from X-th word, until !#X-

in direct response to example given:

mkdir tmp && cd !#2

or, taking it a step further:

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

the path /tmp/${PWD:t} would be created also and act as an alternative to cd to if for some reason ./tmp could not be created (which would have failed silently)

this assumes user can mkdir in /tmp and is willing to let some useless paths be generated (and left untouched) when ./tmp is perfectly usable and in fact chosen

potential problem arises when /tmp/${PWD:t} already exists and its contents are unrelated and not be disturbed, hence the pwd; ls

aliasing helps with use cases such as somecommand; mktmpd where normally the !#2-3 would no longer refer to the appropriate parameters tmp /tmp/${PWD:t}

Note however that I am decidedly not advocating for this use case as an especially helpful one (or even its fitness as an example, really - but I wanted to point out the alias particularity since I have yet to see it mentioned elsewhere)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top