Command line move file with long directory path without repeating directory path

Solution 1:

You can use bash's brace expansion. This:

mv my/file/that/has/a/really/long/path/foo.{bar,baz}

will expand into:

mv my/file/that/has/a/really/long/path/foo.bar my/file/that/has/a/really/long/path/foo.baz

and then mv is run with those two arguments. See http://wiki.bash-hackers.org/syntax/expansion/brace for more on brace expansion.

Solution 2:

As an alternative to brace expansion, you could use the bash shell's history expansion features:

  • ! introduces a history expansion
  • # event designator denoting the current command
  • $ word designator referring to the last argument

You can perform substitutions on the expansion using a sed-like s/pattern/replacement syntax e.g.

somecommand path/to/foo.bar !#$:s/.bar/.baz

Ex.

$ mv -v somepath/Original/Dir3/SubDir1/foo.bar !#$:s/.bar/.baz
mv -v somepath/Original/Dir3/SubDir1/foo.bar somepath/Original/Dir3/SubDir1/foo.baz
'somepath/Original/Dir3/SubDir1/foo.bar' -> 'somepath/Original/Dir3/SubDir1/foo.baz'

If you want the path specifically (for example, to mv a file to a completely different name that is not easily obtained by substitution), you can use the h modifier:

$ mv -v somepath/Original/Dir3/SubDir1/foo.baz !#$:h/baz.foo
mv -v somepath/Original/Dir3/SubDir1/foo.baz somepath/Original/Dir3/SubDir1/baz.foo
'somepath/Original/Dir3/SubDir1/foo.baz' -> 'somepath/Original/Dir3/SubDir1/baz.foo'

For other options, including readline key combinations to yank the last argument, see How to repeat currently typed in parameter on bash console?

Solution 3:

You might try:

pushd .
cd /really/long/directory/name/
mv whatever.1 whatever.2
popd

Solution 4:

With a variable

  1. Save the directory in a variable : `DIR=./really/long/path/
  2. use move : mv "$DIR"foo.bar "$DIR"foo.bz

In one line : DIR=./really/long/path/; mv "$DIR"foo.bar "$DIR"foo.bz


Changing directory

  1. You could also cd to the directory you want to work in : cd ./really/long/path
  2. then change the file name : mv foo.bar foo.bz

In one line : cd ./really/long/path && mv foo.bar foo.bz