我正在尝试从数组中任意数量的字符串构造-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 "$@"