-1

I want to change these filenames

download (19).download
...
download (27).download

to

download (19).html
...
download (27).html

I run unsuccessfully

mv *.download *.html
usage: mv [-f | -i | -n] [-v] source target
       mv [-f | -i | -n] [-v] source ... directory

How can you change the filename? I think I need a regex here probably.

  • This question has been asked here quite often. There should be dozens of duplicates. – Hauke Laging Apr 03 '14 at 14:10
  • Just learn some scripting language (awk?)... this will not only help to solve questions like this one, but zillions of other problems too... really! It's fun... especially awk ist rewarding your invested time really fast... only a few hours with an awk tutorial and you are settled to gain world domination... mwhuaaahahahahahahahaa! –  Apr 03 '14 at 14:45
  • @yeti You rename files with awk...?? – Hauke Laging Apr 03 '14 at 14:53
  • @HaukeLaging ... yes I can \o/ ... and I can do it in several other languages being installed by default too. I never will install a special file-rename-utility... I am sitting in front of too many different systems (often with only the basic tools being installed) and getting along without "warm-showerer-utilities" has saved my day more than once... so I always vote for learning some swiss army knive tool like awk instead of installing a special tool for every differnent fart... –  Apr 03 '14 at 15:00
  • @yeti The question was not: "Can you rename files with awk"... – Hauke Laging Apr 03 '14 at 15:27
  • @HaukeLaging ... I really do it sometimes... depending on the context... but that was not the point I wanted to underline with my 1st comment... :-( ...keiner versteht mich!!! )-: –  Apr 03 '14 at 15:44

4 Answers4

4

You can only use mv to move multiple files to a single directory in on call. One option here is to use prename (rename is linked to this on most systems, but not all):

prename -n 's/download$/html/' -- *.download

Remove -n when you are sure this is doing what you want. Another way is simply to use a loop:

for file in *.download; do
  mv -i -- "$file" "${file%download}html"
done

The -i option is added mv to prompt if any files will be overwritten. Remove this if you are sure that you will not overwrite any files you need.

Graeme
  • 34,027
  • I remember answering the same sort of question yesterday where you had suggested prename – Ramesh Apr 03 '14 at 14:18
  • @Ramesh, yes, this kind of question has been answered countless times. – Graeme Apr 03 '14 at 14:26
  • I am now on OSX and so prename command there. Any substitute? – Léo Léopold Hertz 준영 Apr 03 '14 at 16:02
  • 1
    @Masi, afraid not, there is no standard utility for this kind of thing. The only portable approach is to run mv for each file, which can be very slow. prename is just a short perl script though. I can't find the original source for it, but it can be downloaded here - https://github.com/subogero/rename – Graeme Apr 03 '14 at 16:35
1

mv doesn't work this way. You need another tool like rename or mmv. Please mind that there are two versions of rename around.

And, of course, the shell can do that (with mv):

for file in *.download; do
  fbasename="${file%.download}"
  if [ -e "${fbasename}.html" ]; then
    echo "${fbasename}.html exists; skipping."
    echo "${fbasename}.html exists; skipping." >>rename.log
    continue
  else
    echo mv -- "$file" "${fbasename}.html"
  fi
done

Remove the echo after testing.

The mmv way:

mmv -n '*.download' '#1.html'

-n prevents execution and shows you what would be done.

Hauke Laging
  • 90,279
0

rename 's/download$/html/' *.download should work for you

doneal24
  • 5,059
0

If you happen to have zsh shell available, then zmv does almost exactly what you want, with very similar syntax:

zmv '*.download' '$1.html'

Just to point out why your attempt was wrong and dangerous: the wildcards *? are expanded by your shell before the command is even called. So, mv actually receives the entire list of files instead of *.download, but *.html has two ways of behaving (both quite bad):

If *.html doesn't exist, your shell leaves the asterisk as part of the filename. You are attempting to move all the downloads to the same file named *.html. mv warns you that it's not a directory (otherwise you would just overwrite this file a number of times and end up with *.html containing the last download). If *.html does find one or more files, shell expands this into a list of files. Hopefully, none of them are directories, so this fails again for the same reason.

Note that you are extremely lucky, you could have lost data this way.

orion
  • 12,502