变量“-name”主要是“find”

变量“-name”主要是“find”

我正在尝试从数组中任意数量的字符串构造-name该命令的复合主键,其形式为.虽然在终端中显式输入名称“primary”是可行的,但将其存储在变量中并通过参数扩展调用它则不行。由于扩展将在运行之前进行,因此我认为问题与扩展变量的引用有关。find\( -name ${a[0]} -or -name ${a[1]} -or -name ${a[2]} ... \)find

下面是 n=2 个名称的最小示例,可以按字面输入,也可以从变量中调用。虽然我意识到我可以通过管道传输到,但在这种情况下grep我更愿意做所有事情。find

$ ls
a1  a2  b1  b2  c1  c2

$ find . \( -name a\* -or -name b\* \)
./a1
./a2
./b1
./b2

$ names="\( -name a\* -or -name b\* \)"

$ printf "%s\n" "$names"
\( -name a\* -or -name b\* \)

$ find . $(printf "%q" "$names")
find: -name\: unknown primary or operator

$ find . $(printf "%s" "$names")
find: \): unknown primary or operator

$ find . $names
find: \): unknown primary or operator

$ find . "$names"
find: \( -name a\* -or -name b\* \): No such file or directory

答案1

每个-name、每个-or、每个括号和每个模式都必须是一个单独的参数find。不要将参数之间用空格连接起来:您无法从那里返回到参数列表 - 您如何知道哪些空格用于分隔参数以及哪些空格是参数的一部分?也可以看看为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?

如果您的 shell 支持数组(ksh、bash、zsh),请将参数列表存储在数组中。

names=(\( -name a\* -or -name b\* \))
find "${names[@]}"

如果您的 shell 不支持数组,您可以在位置参数(可以通过$1, $2, ... 访问的参数)中构造列表。明显的限制是您不能将位置参数用于其他目的。

set -- \( -name a\* -or -name b\* \)
find "$@"

相关内容