3

I am trying to locate all .jpg picture files in my current directory and sub-directories and move them to another directory. I want the source files to overwrite the destination files, but that is not happening. When I run my command, I am getting the following output for some files (but others were moved):

mv: cannot move './file' to '/destination': File exists

Here is the command I am using:

find . -iname *jpg -execdir mv -f {} \;

It seems like the -f (force) option is not working?

When I went back and did mv -f ./source/file /dest on a single file, it did overwrite properly.

What's the deal? Why is the file not being moved?


UPDATE: The command listed above is not what I actually passed (sheepishly sighs). The actual command did include a destination (as previously suggested in the answer from @Gilles):

find . -iname '*jpg' -execdir mv -f {} /destination \;

I passed this command again to make sure I actually included the /destination directory, and I received the same error:

mv: cannot move './file' to '/destination': File exists

Are there any possible answers to why this error would show, even with a /destination directory in the mv command?

2
  • 1
    What is the filesystem type on the destination? What does ls -ld /destination /destination/file show? What does strace -s9999 mv -f ./file /destination show? Nov 17, 2011 at 1:36
  • @Gilles -- sorry for the delayed response. Long story. I was working in a Gparted Live disk when I was having this issue. The /source and /destination were on an external HD. I just plugged the external into a machine running Ubuntu 10.04, ran the command, and didn't get the same output -- I assume the files moved. Anyway, thanks for the input. I'm a bit confused, but moving on. Maybe something with Gparted, maybe something with newbie user error?!
    – Brian Dant
    Nov 23, 2011 at 23:20

1 Answer 1

5

The command you claim to be executing doesn't match the error message you're getting, but either way this answer should clarify some things.

First, note that if there are any files matching *jpg in the current directory, the pattern *jpg will be expanded on the command line of find. You need to quote the pattern to protect from that.

With the command you've given, what gets executed is something like

cd directory && mv -f file

But mv expects two arguments: a source file and a destination.

You need to pass a target directory, and since you're using -execdir, the target directory will be interpreted relative to each directory where there are .jpg files. Note that the directory must exist. If you want to move all .jpg files to a single directory, create it first, then run

find -iname '*.jpg' -execdir mv -f {} /common-destination-directory

If you want to move all files to a relative path, for example move them to the images subdirectory relative to where they are, you will need to create the directory first.

find -iname '*.jpg' -execdir mkdir -p images \; -execdir mv -f {} images \;

With GNU utilities (i.e. on Linux) you can optimize a little by running mv only once per directory:

find -iname '*.jpg' -execdir mkdir -p images \; -execdir mv -t images {} +
1
  • This was a great answer, and did certainly improve my knowledge. Sorry about the error in my post. Does the UPDATE posted above clarify anything that might expand your answer?
    – Brian Dant
    Nov 15, 2011 at 18:47

You must log in to answer this question.

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