在zsh
中,通过 glob 扩展,我们可以使用P
标志在每个匹配项前添加一些文本:
$ ls -1
bar
baz
foo
$ print -- *(P:--file:)
--file bar --file baz --file foo
数组参数有类似的东西吗?如果我写
items=(foo bar baz)
是否有一些标志可以用来获得这样的行为?
$ print -- ${(...)items}
--file foo --file bar --file baz
在zsh
中,通过 glob 扩展,我们可以使用P
标志在每个匹配项前添加一些文本:
$ ls -1
bar
baz
foo
$ print -- *(P:--file:)
--file bar --file baz --file foo
数组参数有类似的东西吗?如果我写
items=(foo bar baz)
是否有一些标志可以用来获得这样的行为?
$ print -- ${(...)items}
--file foo --file bar --file baz
最佳答案取决于您需要修改后的数组的用途。
如果您正在生成命令行参数(如问题中所示),并且您正在使用一个接受标志的工具
--file=foo
作为替代--file foo
,最惯用的方法是使用${^name}
扩展形式:我
print -lr
用来证明扩展会产生一个包含三个元素的数组。如果您调用这样的命令,该命令将看到三个参数。如果您正在生成命令行参数,则可以将要添加的文本(
--file
在本例中)放在一个虚拟数组中,并使用${name:^^arrayname}
扩展形式将其与参数数组组合:这是一个包含六个元素的数组。这种格式或 (1) 中的一种格式——或两者兼而有之——应该可以被几乎任何用于传递带有关联值的标志的命令行工具所接受。
您可以修改 (1) 中的方法以使用空格而不是等号:
(请注意,您必须用反斜杠转义空格;使用双引号
"--file ${^items}"
表示其他含义。)这是一个包含三个元素的数组,但每个元素中都有一个嵌入的空格。很少(如果有的话)命令行工具会接受这种格式的标志,但它可能对其他类型的文本操作很有用。你也可以使用
${name/pattern/repl}
扩展的形式。模式应该以#
(表示它需要在每个数组元素的开头匹配)开始,但它应该是空的(这样每个数组元素都会匹配,因此实际上不会替换任何文本)。这与 (3) 有相同的注意事项,而且它也没有这种方法那么惯用。
请注意,当数组元素包含空格时,所有这四种方法都会做正确的事情(即它们不会突然在空格上拆分字符串)。
您可以使用
P
glob 修饰符!如果你坚持,一切都可以是一个球。请注意,我并不是说我真的想这样做。我想不出最好的方法。但这在技术上是可行的。它的工作原理是创建一个与一个文件名完全匹配的 glob(
/
会很好),使用 glob 限定符e
将一个匹配项替换为任意列表,并将P
限定符应用于结果。这仅适用于执行 globbing 的上下文,但这通常是允许使用数组的情况。
您可以通过以下方式可移植地执行此操作(或至少可移植到支持此数组语法的 shell)
printf
:然而,与该
print
命令不同的是,它不会添加尾随换行符(这就是为什么您在$
上面的输出中具有与输出相同的行的原因)。如果这是一个交易破坏者,你可以这样做: