uuidgen 和 $RANDOM 在 find -exec 参数中没有改变

uuidgen and $RANDOM doesn't change in find -exec argument

我想获取 macosx 文件系统中文件的所有实例,并将它们复制到外部硬盘的单个文件夹中。 我在终端中写了一行简单的代码,但是当我执行它时,目标文件夹中只有一个文件,它在每次发现时都会被替换。 似乎在单个命令中使用的 $RANDOM 或 $(uuidgen) return 只有一个值用于 find 命令的每次出现 {}。 有没有办法为 find 命令的每个结果获取一个新值? 谢谢。

find . -iname test.txt -exec cp {} /Volumes/EXT/$(uuidgen) \;

find . -iname test.txt -exec cp {} /Volumes/EXT/$RANDOM \;
find . -iname test.txt -exec bash -c '
    for i do
        cp "$i" "/Volumes/EXT/$RANDOM"
    done' _ {} +

您可以使用 -exec+,将多个文件传递到 bash 循环。您不能在单个 -exec.

中使用命令子(或多个命令)

这应该有效:

find ... -exec bash -c 'cp "" /Volumes/somewhere/$(uuidgen)' _ {} \;

感谢 dan 和 pjh 在评论中的更正。

如果您有 Bash 4.0 或更高版本,另一种选择是:

shopt -s dotglob
shopt -s globstar
shopt -s nocaseglob
shopt -s nullglob

for testfile in **/test.txt; do
    cp -- "$testfile" "/Volumes/EXT/$(uuidgen)"
done
  • shopt -s dotglob 使 glob 能够匹配以 . 开头的文件和目录(例如 .dir/test.txt
  • shopt -s globstar 允许使用 ** 通过目录树递归匹配路径
  • shopt -s nocaseglob 导致 glob 以 case-insensitive 方式匹配(如 find 选项 -iname-name
  • shopt -s nullglob 使 glob 在没有匹配项时展开为空(否则它们会展开为 glob 模式本身,这在程序中几乎没有用)
  • cp -- ... 中的 -- 防止以连字符开头的路径(例如 -dir/test.txt)被(错误)视为 `cp'
  • 的选项
  • 请注意,此代码在 4.3 之前的 Bash 版本上可能会失败,因为在扩展 ** 模式时会(愚蠢地)遵循符号链接