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?

  • 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 5, 2012 at 7:41
  • 1
  • 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 5, 2012 at 8:14

4 Answers 4


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
  • 2
    Very useful and - for me - the most common case to use brace expansion. Thanks to this, I hardly ever use rename. Apr 5, 2012 at 8:34

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

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}

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.


You can define function:

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


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

Not the answer you're looking for? Browse other questions tagged .