7

If I want to move a file called longfile from /longpath/ to /longpath/morepath/ can I do something like

mv (/longpath)/(longfile) $1/morepath/$2

i.e. can I let the bash know that it should remember a specific part of the input so I can reuse it later in the same input? (In the above example I use an imaginary remembering command that works by enclosing in parantheses and an imaginary reuse command $ that inserts the content of the groups)

Bananach
  • 455
  • 2
    Why not a variable then? – heemayl Mar 29 '16 at 13:27
  • For example, the above fits in one line and doesn't leave two variables behind that are never used again. I am not sure if there are more advantages/applications, I was mostly curious – Bananach Mar 29 '16 at 13:30

4 Answers4

24

You could do this:

mv /longpath/longfile !#:1:h/morepath/

See https://www.gnu.org/software/bash/manual/bashref.html#History-Interaction

  • !# is the current command
  • :1 is the first argument in this command
  • :h is the "head" -- think dirname
  • /morepath/ appends that to the head
  • and you're moving a file to a directory, so it keeps the same basename.

If you want to alter the "longfile" name, say add a ".txt" extension, you could

mv /longpath/longfile !#:1:h/morepath/!#:1:t.txt

Personally, I would cut and paste with my mouse. In practice I never get much more complicated than !! or !$ or !!:gs/foo/bar/

glenn jackman
  • 85,964
15

You could also do this with brace expansion:

mv /longpath/{,morepath/}longfile

The shell expands this so that the mv command sees it the same as:

mv /longpath/longfile /longpath/morepath/longfile
Wildcard
  • 36,499
9

If you are for more efficient typing in command line, you may find various readline shortcut useful. Readline is already built-in your shell. For your paricular case you could yank/delete parts of your line and then recall them from readline killiring.

Moreover, if you have EDITOR environmnent variable set to your favorite editor, then Ctrl-X,Ctrl-E will copy your current command line into editor window where you can have all the editor power to modify your line. Once completed, you save/exit from the editor and the line gets executed in your shell.

Tagwint
  • 2,480
  • After having spent weeks on learning vim, I was actually upset that I still had to hold the left-arrow in the console forever to move around in my commands. Now I can apply all my newly acquired vim magic for that. Wonderful! – Bananach Mar 29 '16 at 14:45
  • 2
    @Bananach: you can also set bash to vi-mode: set -o vi in bashrc. Then pressing esc on the command line puts you in the equivalent of vim's normal mode. – Nick Matteo Mar 30 '16 at 13:58
  • 1
    @kundor, I use set -o vi myself, but it's not nearly as powerful as Vim's normal mode—it has a subset of the commands of POSIX vi. Still very useful, though, and you can use <Esc>v to open the command for editing in Vim. – Wildcard Mar 30 '16 at 22:31
4

For something like the specific case you are asking about, you can also use a subshell.

mv (/longpath)/(longfile) $1/morepath/$2

becomes

( cd /longpath; mv longfile morepath/ )

while keeping your current working directory in the shell you are working in.

This isn't entirely dissimilar to Wildcard's suggestion of using shell expansion but can be done for more complex situations than a simple something-here-in-one-argument-only can readily support.

user
  • 28,901
  • Worth noting that the spaces around the parentheses are for readability; they're not required (unlike using curly braces for command grouping where whitespace separation is required). – Wildcard Mar 30 '16 at 22:29