当不存在同名但扩展名不同的文件时,将所有文件从一个文件夹复制到另一个文件夹

当不存在同名但扩展名不同的文件时,将所有文件从一个文件夹复制到另一个文件夹

我有一台 IP 摄像头,它会将录像保存到我的 Samba 共享中。我想在完全保存后将这些文件复制到其他位置。

现在我的问题是:相机需要一些时间将.avi格式为(名为motion-date.avi)的文件复制到我的共享位置,同时它还会创建一个同名的.idx文件(名为motion-date.idx),完成后该文件将被删除。

所以我想将所有.avi没有对应.idx文件的文件复制到不同的文件夹。

答案1

find /source/dir/ -type f -name '*.avi' -exec sh -c 'test ! -f "${1%.*}.idx" && cp "$1" /target/dir/' sh {} \;

此命令查找.avi下的所有文件/source/dir/并为每个文件生成一个基本 shell。然后,shell 会测试是否存在相应的文件,并在需要时.idx调用。cp


编辑:我稍微修改了命令,使其更加万无一失。根据明确要求,我更详细地解释了整个命令。

  • find- 寻找…
  • /source/dir/–...在给定的目录中...
  • -type f…所有文件…
  • -name '*.avi'– …名称符合以下模式…
  • -exec– ...对找到的每个文件执行...
  • sh -c '…' sh {}– ...执行命令的 shell;在 shell 内部,路径可用为$1,因为{}会被替换为找到的特定文件的实际路径(这就是find -exec工作原理)。
  • \;– 这表明了-exec结束的地方。

每个 shell 都有-c一个选项,告诉它执行下一个参数,就像输入命令一样。命令如下:

  • test– 相应地测试并返回退出状态;以下参数将告诉要测试什么。
    • !– 注意:测试是相反的。
    • -f– 测试是否存在现有文件...
    • "${1%.*}.idx"– ...在此路径下。该${1%.*}构造告诉 shell 获取参数的内容,而不获取从最后一个点.到末尾的片段。我附加了另一个扩展名。这样我就交换了它们。
  • &&– 仅当前一个命令(即test)返回退出状态时0……
  • cp- …复制…
    • "$1"– …已找到的文件find
    • /target/dir/– …到目标目录。

最后说明:

  • 我需要一个 shell 来处理"${1%.*}.idx"&&。如果我想复制找到的每个文件,那么… -exec cp {} /target/dir/ \;就足够了(虽然远非最佳,但我们不要分心)。
  • 引用(例如"")每条路径是很好的可能包括空格,特殊字符等。
  • 的参数(命令)sh是单引号('')。如果是双引号(""),则 的扩展"${1%.*}.idx"将发生在当前 shell(运行 的 shell find)中,而这不是我想要的。您可以阅读更多这里

相关内容