我想使用 find 来定位文件,然后将它们复制到目录中,所以我尝试:
find . -name '*.png' -exec cp {} /tmp/dest +
但是,这会失败
find: missing argument to `-exec'
当我用+
a替换它时;
,它可以工作,但会单独为每个文件调用 cp 。使用+
形式时如何添加尾随参数(例如目标目录)-exec
?
当然,在这种情况下,我可以通过使用cp -t
(如中所示)来解决明显的限制Stack Overflow 上的这篇文章,但该解决方案特定于cp
.相反,我可能会使用 rsync、scp 或其他一些工具。有没有通用的方法在{}
和+
之间添加参数find -exec
?
答案1
不,如果您使用,则除了空格之外-exec ... {} +
可能没有任何内容。没有办法解决这个问题。{}
+
来自 POSIX 标准规范命令find
:
-exec utility_name [argument ...] ;
-exec utility_name [argument ...] {} +
主要表达式的末尾应使用 a
<semicolon>
或 a进行标点<plus-sign>
。只有<plus-sign>
紧跟在仅包含两个字符的参数后面的a 才{}
应标点主表达式的末尾。的其他用途<plus-sign>
不应被视为特殊用途。
更通用的解决方案可能是
find ... -exec sh -c 'cp "$@" /tmp/dest' sh {} +
在这里,sh -c
使用来自 的批量参数执行内联脚本find
。在内联脚本内部,"$@"
将是传递的参数列表(单独引用),这允许我们将它们按照我们想要的方式放置在cp
命令行上。
这允许我们使用非 GNU cp
(例如 macOS 或其他 BSD 系统,其中没有-t
选项)或任何其他实用程序,人们可能希望将其他参数添加到来自find
.
有关的:
没有人要求这个,但无论如何......
将目标目录放在变量中destdir
:
destdir=/tmp/dest
find ... -exec sh -c 'destdir=$1; shift; cp "$@" "$destdir"' sh "$destdir" {} +
请注意,destdir
shell 中的调用是与脚本中的find
单独变量。destdir
sh -c
或者,与bash
:
destdir=/tmp/dest
find ... -exec bash -c 'cp "${@:2}" "$1"' bash "$destdir" {} +
这是对"$@"
列表进行“切片”,以针对命令行适当地重新排列它cp
,而不将$1
目标目录路径名提取到单独的变量中。