我想使用 find 来定位文件,然后将它们复制到一个目录中,所以我尝试了:
find . -name '*.png' -exec cp {} /tmp/dest +
Run Code Online (Sandbox Code Playgroud)
然而,这失败了
find: missing argument to `-exec'
Run Code Online (Sandbox Code Playgroud)
当我用+
a替换;
它时,它可以工作,但会单独为每个文件调用 cp 。使用 的+
形式时如何添加尾随参数(例如目标目录)-exec
?
当然,在这种情况下,我可以通过使用来解决明显的限制cp -t
(例如在 Stack Overflow 上的这篇文章中指出,但该解决方案特定于cp
。相反,我可能会使用 rsync、scp 或其他一些工具。是否有在{}
和+
in之间添加参数的一般方法find -exec
?
Kus*_*nda 12
不,如果你使用的-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 {} +
Run Code Online (Sandbox Code Playgroud)
在这里,使用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" {} +
Run Code Online (Sandbox Code Playgroud)
请注意,destdir
在shell调用的find
是一个独立的变量将destdir
在sh -c
脚本中。
或者,使用bash
:
destdir=/tmp/dest
find ... -exec bash -c 'cp "${@:2}" "$1"' bash "$destdir" {} +
Run Code Online (Sandbox Code Playgroud)
这是“切片”"$@"
列表,以便为cp
命令行适当地重新排列它,而不$1
将目标目录路径名提取到单独的变量中。