例子

例子

我在另一个目录的子目录中有许多图像,我想将它们复制到一个目录中,以便所有图像都集中在一个地方。

经过一番搜索,我找到并修改了一些内容来创建此命令:

find . -name "z*.jpg" -exec cp '{}' ~/Extracted/ \;

这似乎有效,但是我发现同名的图像会被覆盖,所以我这样做了:

find . -name "z*.jpg" -exec cp -n '{}' ~/Extracted/ \;

但现在同名的图像会被忽略。

有什么办法可以做到这一点,以便复制每个图像并重命名同名图像?

答案1

GNUcp(1)有一个备份选项:

cp --backup SOURCE [SOURCE...] [DESTINATION]

这具有以下效果,可以通过其他选项进行控制,如手册页cp(1)

--backup[=CONTROL]
          make a backup of each existing destination file

-b     like --backup but does not accept an argument

-S, --suffix=SUFFIX
          override the usual backup suffix

备份后缀为~,除非使用--suffix或 进行设置SIMPLE_BACKUP_SUFFIX。版本控制方法可以通过选项--backupVERSION_CONTROL环境变量进行选择。以下是值:

  • none, off:从不进行备份(即使--backup给出了)
  • numbered, t:进行编号备份
  • existing, nil:如果存在编号备份,则使用编号,否则使用简单
  • simple, never:始终进行简单备份

例子

cp --backup=existing --suffix=.orig ~/Music/* ~/Videos

这会将所有文件复制到~/Music~/Videos如果目标中存在同名文件,则通过.orig在其名称后附加 来重命名该文件作为备份。如果存在与备份同名的文件,则通过附加 来重命名备份(.1如果备份也存在),.2依此类推。只有这样,源文件才会复制到目标。

如果要递归复制子目录中的文件,请使用-R

cp -R --backup=existing --suffix=.orig ~/Music ~/Videos

答案2

您的问题实际上是找到一个cp变体,如果目标文件已经存在,则以不同的名称创建它。我不知道有这样的工具,但是,自己实现并不难:

cp -vn "$1" "$2"/ || cp -vn "$1" "$2"/"${1##*/}"~"$(md5sum "$1" | cut -f1 -d' ')"

如果失败,此脚本将cp再次调用,将校验和附加到文件名中。缺陷:如果出现第三个同名文件,它将覆盖第二个文件如果它们相同

假设上述脚本被调用saveCopy并存储在父工作目录中,则以下内容有效:

$ find . -name 'z*.jpg' -exec ./saveCopy {} /tmp/Extracted/ \;
./a/z1.jpg -> /tmp/Extracted/z1.jpg
./a/z2.jpg -> /tmp/Extracted/z2.jpg
./a/z3.jpg -> /tmp/Extracted/z3.jpg
/tmp/Extracted/z3.jpg not overwritten
./b/z3.jpg -> /tmp/Extracted//z3.jpg~d41d8cd98f00b204e9800998ecf8427e
./b/z4.jpg -> /tmp/Extracted/z4.jpg

请注意,该脚本仅适用于单个输入文件,并且目标为目录!它当然可以改进 ;-)

答案3

在 Catalina 上运行的 GNU cp 的自制版本似乎存在一个错误,当它复制到包含大量(几千个)文件的目录并使用 --backup 重命名文件时,会导致它挂起。通过减少目标目录中的文件数量解决了这个问题。例如,对于 1000 个文件,它按预期工作。

相关内容