44

Possible Duplicate:
Reuse text on a bash command

If I want to rename a file a few directories deep, how can I avoid repeating the path?

For example:

mv path/to/old_filename.txt path/to/new_filename.txt

I'm wondering if there's a way to make this:

mv path/to/old_filename.txt (?)new_filename.txt

Where (?) would be some way of saying "in the same directory."

Nathan Long
  • 26,015
  • 36
  • 102
  • 139

4 Answers4

65

You can use brace expansion: mv path/to/{old_filename.txt,new_filename.txt}

Here is a link to the GNU guide on brace expansion in the bash shell, which defines a list of substitutes and tells bash to repeat the parameter using a different substitute each time it repeats.

For example,

a{b,c,dd,e}

will be expanded to

ab ac add ae

The only caveat is that the expanded repetitions must be able to follow each other as arguments to the target program.

Darth Android
  • 37,872
  • 5
  • 94
  • 112
  • 6
    Or keeping it to a minimum: `mv path/to/{old,new}_filename.txt`. This also helps reversal or other kinds of close-to-repetition of the command. I have many times done e.g. `mv /etc/X11/xorg.conf{,.backup}`, being able to reverse the process by the simple change `mv /etc/X11/xorg.conf{.backup,}`. – Daniel Andersson Mar 21 '12 at 16:03
30

Using bash history expansion:

mv path/to/oldfile !#:1:h/newfile

where !#:1:h means: from the line you're currently typing ("!#"), take the first word (":1"), then take only the path component (":h" -- the head) from it.

glenn jackman
  • 25,463
  • 6
  • 46
  • 69
  • This is the closest to what the original questioner assumed the solution might be, and is useful to know, so +1. – crazy2be Jun 16 '11 at 20:28
  • 2
    Cool! I think Darth's brace expansion method is easier, but this is exactly what I asked for. – Nathan Long Jun 24 '11 at 15:29
  • I've learned two great new things today. Also, I will forever think of brace expansion as "Darth's brace expansion" because it sounds awesome. – sqlHippo Jul 13 '11 at 15:32
28

Darth's answer above is clever, but if you want to use an approach with cd, you could also consider using a subshell:

(cd path/to && mv old_filename.txt new_filename.txt)

Because the directory change takes place in the subshell, you will not actually change directories in your interactive shell.

mlc
  • 381
  • 2
  • 4
11

Another alternative that is useful, if you are going to do several commands in the directory, is this:

pushd /path/to
mv oldfile newfile
...
popd
Nathan Long
  • 26,015
  • 36
  • 102
  • 139
KeithB
  • 9,976
  • 2
  • 23
  • 17