36

Often I will work out of the root of a rails directory where I find my self navigating the same path twice every time I would like to move a file:

mv app/views/layouts/application.html.erb app/views/layouts/application.html.haml

The haml is just one of may examples where I need to change the file name without modifying the directory it currently lives in and without changing directory. Is there a way to achieve this?

rudolph9
  • 1,425
  • I remember seeing a question with an accepted answer nearly identical to mine. However I cannot find it so I've answered your question for now, at least until someone stumbles across the link. – jw013 Apr 05 '12 at 07:41
  • 1
    http://unix.stackexchange.com/questions/6035/when-do-you-use-brace-expansion – bbaja42 Apr 05 '12 at 07:45
  • 3
    While the answers are the same, the questions are rather different. That one is "I have a tool, but what's it good for?" and this one is "I have a problem, what tool should I use?" It's probably worth keeping both. – cjm Apr 05 '12 at 08:14

4 Answers4

59

Use brace expansion:

mv very/long/path/to/filename.{old,new}

would expand to

mv very/long/path/to/filename.old very/long/path/to/filename.new
jw013
  • 51,212
8

If you're going to work in a directory, you can switch to it temporarily.

pushd app/views/layouts
mv application.html.erb application.html.haml
popd

Under Linux, you can use the rename utility (called rename.ul under Debian, Ubuntu and derivatives) to change a part of the file name (which can be in the directory part). rename foo bar path/to/file changes the first occurrence of foo in path/to/file to bar. If a file name doesn't contain the first string, the file is left in place.

rename .erb .haml app/views/layouts/application.html.erb
rename .erb .haml app/views/layouts/*.html.erb       # do several in one go
rename .erb .haml app/views/layouts/application.*    # never mind if application.js and application.html.gz also exist

When you have several consecutive words in a comman line that share a common stem, you can use brace expansion:

mv app/views/layouts/application.html.{erb,haml}
4

You could cd in the directory in a sub-shell:

(cd app/views/layouts && mv application.html.erb application.html.haml)

Here, the parentheses execute the commands in a new bash shell process.

jfg956
  • 6,336
3

You can define function:

mv-rename () {
  mv -- "${1}" "$(dirname -- "${1}")/${2}"
}

Usage:

mv-rename app/views/layouts/application.html.erb application.html.haml
anlar
  • 4,165