Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Possible Duplicate:
How to clean up file extensions?

I'd like to rename files with extension .flac.mp3 to extension .mp3. I used the following command

$ for i in *; do mv $i `echo $i | sed 's/.flac//g'`; done

This writes for every file the following error message.

mv: target `file.mp3' is not a directory

Where am I doing mistake?

thank you

share|improve this question

marked as duplicate by Gilles, Michael Mrozek Jun 11 '11 at 20:19

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1 Answer 1

up vote 4 down vote accepted

Maybe these files have names containing whitespace.

Simple rule of shell programming: Always use double quotes around variable and command substitutions (unless you know why you need to leave them out). So:

for i in *; do mv "$i" "$(echo "$i" | sed 's/.flac//g')"; done

While you're at it, there are a few things you could do better in that command, even if they aren't the source of your problem. You should run your command only on the files it's supposed to affect, not every file in the current directory. The sed regexp .flac could match something other than the extension. The command may also fail if you have a file name that begins with a - or that contains a backslash (with some versions of echo).

for i in *.flac.mp3; do mv -- "$i" "$(echo "$i" | sed 's/\.flac\.mp3$/\.mp3/')"; done

But in fact you needn't bother with sed here, there's a shell construct to remove a suffix from a string.

for i in *.flac.mp3; do mv -- "$i" "${i%.flac.mp3}.mp3"; done

-- ensures that even if $i begins with a -, it won't be interpreted as an option. An alternative method is to ensure that $i never begins with -, for example by ensuring that all relative file names are prefixed with ./ (which has no effect on what file is designated since . is the current directory).

    for i in ./*.flac.mp3; do mv "$i" "${i%.flac.mp3}.mp3"; done

There are plenty of tools to automate file renamings; browse here for a few ideas. For example, if your shell is zsh:

autoload zmv    # goes into your .zshrc
zmv '(*).flac.mp3' '$1.mp3'
share|improve this answer
    
why do you use "--" in 'do mv -- "$i"'? It works fine at least in my machine without "--". –  user2362 Apr 10 '11 at 16:08
1  
-- is needed when $i begins with a - (and only then). Try it with a file called -Strange.flac.mp3 or -thats-weird.flac.mp3. –  Gilles Apr 10 '11 at 16:24
    
@evilsoup FYI, -- is completely portable and generalizable. Almost all commands on almost all platforms treat it as an end-of-options marker. There is no portability or pedagogical reason to prefer ./. –  Gilles Jun 27 '13 at 20:44
    
@Giles well... there is always that minority of tools to worry about, but fair enough. I also think that the ./ looks better than the --, and I find it easier to remember, but of course that's subjective :) –  evilsoup Jun 27 '13 at 20:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.