I was just typing something along the lines of:
mv foo/bar/poit/zoid/narf.txt
and suddenly realized, damn, I have to type large parts of that parameter again
mv foo/bar/poit/zoid/narf.txt foo/bar/poit/zoid/troz.txt
Even with tabcompletion, quite a pain. I know I can copy paste the parameter by mouse-selecting the text and middleclick but that is not good enough. I want to remain on the keyboard.
So is there a way to copy paste the current parameter of the line using the keyboard?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
History expansion actually works on the current command as well, using the event designator !#. Combine this with the word designator for the last argument – $ – to get the parameter you just typed. And you can use all the regular modifiers over it, so if, e.g., you are renaming a file in a far away directory, you can just type:
mv path/you/do/not/want/to/type/twice/oldname !#$:h/newname
Method 2
If I’ve planned ahead, I use brace expansion. In this case:
mv foo/bar/poit/zoid/{narf,troz}.txt
Here is another approach using the default readline keyboard shortcuts:
mv foo/bar/poit/soid/narf.txt: start- Ctrl–w:
unix-word-ruboutto deletefoo/bar/poit/soid/narf.txt - Ctrl–y, Space, Ctrl–y:
yank, space,yankagain to getmv foo/bar/poit/soid/narf.txt foo/bar/poit/soid/narf.txt - Meta–backspace, Meta–backspace:
backward-kill-wordtwice to delete the lastnarf.txt troz.txt: type the tail part that is different
If you spend any non-trivial amount of time using the bash shell, I’d recommend periodically reading through a list of the default shortcuts and picking out a few that seem useful to learn and incorporate into your routine. Chapter 8 of the bash manual is a good place to start. Knowing the shortcuts can really raise your efficiency.
Method 3
As in your example, you can use next construction:
mv foo/bar/poit/zoid/{narf.txt,troz.txt}
or even (as suggested Ansgar Esztermann):
mv foo/bar/poit/zoid/{narf,troz}.txt
instead ot typing/copypasting long address twice.
Method 4
Playing around I got this to work:
mv foo/bar/poit/zoid/narf.txt
Hit Enter
to store the last parameter.
Now use ↑ to get last typed in line back. Enter a space and to get the last used parameter use:
Alt + .
I hate provoking an error, but it gets the job done in this use case.
Method 5
This inserts the last word of the Readline line buffer. !# is the current line, :$ is the last word, and e^ is history-expand-line.
"ej":"!#:$e^"
This also works when you’re in the middle of a word, and it doesn’t require inserting a space manually, but it has the disadvantage that it overrides the kill ring:
"ee":shell-backward-word
"ei":shell-forward-word
"ew":copy-region-as-kill
"ej":"eee eiew C-y"
In order to duplicate the previous whitespace-delimited word instead of a shell word, you can use C-wC-yC-y. C-w deletes a whitespace-delimited word backwards.
Method 6
You can easy use variables:
a=test.csv ; cp $a $a.bak
Or in you case (note tab competition works for the a part):
a=foo/bar/poit/zoid/ ; mv ${a}narf.txt ${a}troz.txt
Method 7
For zsh, I find the following keybindings helpful.
# Bind alt-m to insert previous word from the current line bindkey '^[m' copy-prev-shell-word # Bind alt-k to kill word before cursor in vi-style bindkey '^[k' vi-backward-kill-word
So I hit Alt–M to repeat the last argument then Alt–K if I want to delete parts off the end of a path.
Here’s a useful reference to some of the behaviors you can map.
Method 8
A short interactive two step solution
-
type:
echo foo/bar/poit/zoid/narf.txtThis makes
foo/bar/poit/zoid/narf.txtavailable for the Alt–. shortcut in bash. -
type:
mvand hit Alt–., Space, Alt–.You will get
mv foo/bar/poit/zoid/troz.txt foo/bar/poit/zoid/troz.txt.
Now you can modify the last word easily.
Midnight Commander
This tool which might be (very) handy is a file manager running in the console. It gives you the possibility to copy filenames and directory paths interactively into the command line. Midnight Commander shows you therefore 2 panels (left and right), which list the contents of different directories.
A short guide:
- Up/Down arrow keys select files in the current panel.
- Tab switches between left and right panel.
- Ctrl–Shift–Enter copies the currently selected file to the command line (including full path)
- Alt–o opens the currently selected directory in the other panel
- Ctrl–o lets you see the console in full screen
- Ctrl–x, p copies the path of the active panel into the console
- Ctrl–x, Ctrl–p copies the path of the inactive panel into the console
- Esc–Tab is auto completion
This is by far the fastest way I found so far – after I got used to the shortcuts.
Method 9
Use the same thing in the {,} “duplicator”. I.e.:
git tag -m {v,v}1.0.1
# same as
git tag -m v1.0.1 v1.0.1
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0