Can I have a shell alias for evaluating a history replacement command?

I am trying to write an alias for cd !!: 1, which takes the second word of the previous command and changes the directory of that name. For example, if I type

rails new_project cd !!:1 

the second line will be written to the "new_project" directory.

Since !!: 1 is inconvenient to type (although this is short, it requires three SHIFT keys, on opposite sides of the keyboard, and then an unSHIFTed version of the key that was printed twice SHIFTed), I just want to type something like

 cd- 

but since !!: 1 is evaluated on the command line, I (OBVIOUSLY) cannot just do

 alias cd-=!!:1 

or I would save an alias containing the "new_project" encoded in it. So I tried

 alias cd-='!!:1' 

The problem is that !!: 1 is NEVER evaluated, and I get a message stating that no directory named !!: 1 exists. How can I create an alias that evaluates the history substitution. At the time when I ask Alias ​​command, and not when I define an alias, and not never?

(I tried this in both bash and zsh, and get the same results in both.)

+6
bash eval alias zsh history
source share
3 answers

For zsh:

 alias cd-='cd ${${(z)$(fc -l -1)}[3]}' 

How it works:

  • $(fc -l -1) . fc -l {start} [{end}] means "log history commands from {start} to {end} or last if {end} not."
  • ${(z)...} should split ... into an array, as the shell does (see "Parameter extension flags" in man zshexpn ), but in fact it breaks into spaces. Maybe this is just my mistake.
  • ${...[3]} takes the third value from the array. The first value is the command number, the second is the command and the third, and then the arguments.
+6
source share

For bash :

 alias cd-='cd $(history -p !!:1)' 
+9
source share

Another way to do the same thing:

For the last argument:

cd Alt - .

or

cd Esc .

For the first argument:

cd Alt - Ctrl - y

or

cd Esc Ctrl - y

+8
source share

All Articles