mv:A和B是同一个文件

Sha*_*yan 3 bash cygwin find mv

我正在尝试将 5 个 .MOV 文件移动到名为 MOV 的文件夹中。我用来find列出文件并mv移动文件:

$ 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
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这会警告我,我将文件移回原来的位置,这次我echo想看看它在做什么:

$ 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
Run Code Online (Sandbox Code Playgroud)

看起来不错,没有重复。

如果我将目标文件夹命名为 MOV 以外的名称,它就不再发出警告。另外,如果我使用-maxdepth 1它也find不会发出警告。或者我可以简单地使用mv *.MOV MOV. 但我问这个问题是为了了解幕后发生的事情。

我在这里发现了类似的问题:https://askubuntu.com/questions/1143012/why-do-i-get-x-and-y-are-the-same-file-when-using-mv-even-虽然-他们-是-c但答案似乎并没有解释问题,而且回答者说他们后来也偶然发现了这一点。

Kus*_*nda 12

您的find命令将文件移动到MOV当前目录中调用的目录中。

按照您编写命令的方式,它还会在MOV目录中查找文件,当它找到匹配的文件时(如果该MOV目录不是第一个要检查的目录或者您多次运行该命令,则可能会发生这种情况),它会尝试将它们移动到它们已经所在的同一目录,从而产生您看到的诊断消息。

要解决此问题,您可以告诉find避免查看MOV目录内部:

find . -path ./MOV -prune -o -type f -iname '*.MOV' -exec mv {} MOV \;
Run Code Online (Sandbox Code Playgroud)

此-path ./MOV -prune测试当前路径名是否为./MOV,如果是,则将其从搜索路径中删除并继续搜索下一个目录条目。否则 ( -o),它将执行与之前相同的测试和操作。


mv如果您使用 GNU 工具,您可以通过尽可能少地调用来加快速度:

find . -path ./MOV -prune -o -type f -iname '*.MOV' -exec mv -t MOV {} +
Run Code Online (Sandbox Code Playgroud)

如果没有 GNU 工具,您将使用内联脚本执行相同类型的优化:

find . -path ./MOV -prune -o -type f -iname '*.MOV' -exec sh -c 'mv "$@" MOV' sh {} +
Run Code Online (Sandbox Code Playgroud)

在原始命令的这两个变体中,mv将仅使用批量路径名调用几次,而不是每次使用单个路径名多次调用。

如果您只有五个文件,这些优化不会产生太大影响,但如果您有数千个文件,则可能会显着加快速度。