Unix & Linux
bash find mv cygwin
Updated Tue, 04 Oct 2022 21:15:35 GMT

mv: A and B are the same file


I'm trying to move 5 .MOV files to a folder called MOV. I'm using find to list the files and mv to move the files:

$ mkdir MOV ; find . -type f -iname '*.MOV' -exec mv "{}" "MOV" \;
mv: './MOV/IMG_2391.MOV' and 'MOV/IMG_2391.MOV' are the same file
mv: './MOV/IMG_2395.MOV' and 'MOV/IMG_2395.MOV' are the same file
mv: './MOV/IMG_2401.MOV' and 'MOV/IMG_2401.MOV' are the same file

I don't understand why this is warning me, I moved the files back to the original location and this time I echo'd to see what it's doing:

$ mkdir MOV ; find . -type f -iname '*.MOV' -exec echo mv "{}" "MOV" \;
mv ./IMG_2391.MOV MOV
mv ./IMG_2394.MOV MOV
mv ./IMG_2395.MOV MOV
mv ./IMG_2400.MOV MOV
mv ./IMG_2401.MOV MOV

It seems fine, there are no duplicates.

If I name the destination folder something other than MOV, it doesn't warn anymore. Also if I use -maxdepth 1 on find it doesn't warn. Or I could simply use mv *.MOV MOV. But I asked this question to understand what's happening behind the scenes.

I found a similar question on here: https://askubuntu.com/questions/1143012/why-do-i-get-x-and-y-are-the-same-file-when-using-mv-even-though-they-are-c But the answer doesn't seem to explain the issue and the answerer says that they stumbled upon this later as well.




Solution

Your find command moves files into the directory called MOV in the current directory.

The way you have written the command, it will also look for files in the MOV directory, and when it finds matching files there (which may happen if the MOV directory is not the first one to be examined or if you run the command multiple times), it will try to move these to the same directory where they are already located, giving rise to the diagnostic messages that you see.

To fix this, you may tell find to avoid looking inside the MOV directory:

find . -path ./MOV -prune -o -type f -iname '*.MOV' -exec mv {} MOV \;

This, -path ./MOV -prune, tests whether the current pathname is ./MOV, and if so, it removes it from the search paths and continues with the next directory entry instead. Otherwise (-o), it carries out the same tests and actions as before.


If you are using GNU tools, you may speed this up a bit by calling mv as few times as possible:

find . -path ./MOV -prune -o -type f -iname '*.MOV' -exec mv -t MOV {} +

Without GNU tools, you would perform the same sort of optimisation using an in-line script:

find . -path ./MOV -prune -o -type f -iname '*.MOV' -exec sh -c 'mv "$@" MOV' sh {} +

In both these variations of your original command, mv will be called only a few times with batches of pathnames instead of many times with a single pathname each time.

If you only have five files, these optimisations would not make much difference, but if you have thousands of files, it will potentially speed things up significantly.





Comments (3)

  • +0 – This is the Correct Answer , because the Directory Contents are changing while find is running. But @Shayan claims "If I name the destination folder something other than MOV, it doesn't warn anymore." : I think find may still warn , no matter what we name the Destination Directory inside the Source Directory. Depends on when that Directory gets "Processed" by find & whether that Directory is empty or not : We can consider AMOV comes first before IMG , MOV comes after IMG , ZMOV comes last after IMG with ASCII (or Unicode) Sorting. — Aug 14, 2022 at 08:07  
  • +0 – @Prem It depends in which order find sees the directories, yes, but note that the utility does not examine directories in lexicographic (alphabetic) order, but rather in the order that e.g. ls -f would display them in. This is sometimes called "unsorted" or "directory" order. — Aug 14, 2022 at 09:11  
  • +0 – Yes , I imposed that order only to explain my Point , @Kusalananda , that if the empty Directory comes earliest , then there will be no warning , otherwise there will be warning. It is not only that Particular name MOV , which OP was claiming. — Aug 14, 2022 at 10:12