Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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)

share|improve this question
2  
Why not a variable then? – heemayl Mar 29 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 at 13:30
up vote 22 down vote accepted

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/

share|improve this answer

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
share|improve this answer

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.

share|improve this answer
    
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 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. – kundor Mar 30 at 13:58
    
@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 at 22:31

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.

share|improve this answer
    
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 at 22:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.