ere*_*non 5 shell brace-expansion
我正在寻找最简单的解决方案,将其$*作为输入,并扩展到以给定字符串为前缀和后缀的每个元素:
$*=foo bar baz
<solution(x,y)>=xfooy xbary xbazy
Run Code Online (Sandbox Code Playgroud)
我可以进行前置或附加,但不能同时进行:
echo ${*/#/x}
# prints xfoo xbar xbaz
Run Code Online (Sandbox Code Playgroud)
echo ${*/%/y}
# prints fooy bary bazy
Run Code Online (Sandbox Code Playgroud)
我无法结合这两种解决方案。该文档声称在 parameter=* 情况下扩展返回的值是一个列表,但我无法这样使用它。我想将生成的值数组作为单独的参数传递给另一个命令,因此简单地构建单个字符串是行不通的。
Sté*_*las 10
${var/pattern/replacement}是ksh93的参数扩展操作者,也由支撑zsh,mksh以及bash,虽与变化(mksh的目前还不能在阵列上操作)。
在 中ksh93,您需要${var/*/x\0y}在$varwith的扩展前加上x后缀y,并${array[@]/*/x\0y}为数组的每个元素都这样做。
因此,对于位置参数数组:
print -r -- "${@/*/x\0y}"
Run Code Online (Sandbox Code Playgroud)
(但是请注意,对于您的${*/#/x},当位置参数列表为空时会出现问题)。
zsh's等效的ksh93的\0召回匹配字符串中的更换$MATCH,但前提是你使用(#m)的方式(请在您需要的extendedglob选项):
set -o extendedglob
print -r -- "${@/(#m)*/x${MATCH}y}"
Run Code Online (Sandbox Code Playgroud)
但是在 中zsh,您可以嵌套参数扩展,因此您还可以执行以下操作:
print -r -- ${${@/#/x}/%/y}
Run Code Online (Sandbox Code Playgroud)
尽管您可能更愿意使用为该数组的扩展$^array而打开的运算符rcexpandparam,但使其行为类似于大括号扩展:
print -r -- x$^@y
Run Code Online (Sandbox Code Playgroud)
或者你可以使用:
printf -v argv x%sy "$@"
Run Code Online (Sandbox Code Playgroud)
就地修改$@(又名$argvin zsh)(这里假设"$@"不是空列表)。
在bashshell 中,您可能需要使用@L.ScottJohnson 所示的中间数组分两步完成,或者使用以下内容进行修改$@:
set -- "${@/#/x}"
echo -E "${@/%/y}"
Run Code Online (Sandbox Code Playgroud)
(此处假设前缀(x在本例中)不以 开头-)。
您可以使用循环就地修改位置参数:
for i do
set -- "$@" "x${i}y"
shift
done
echo "$@"
Run Code Online (Sandbox Code Playgroud)
(但请注意,echo不能便携地用于显示可能包含反斜杠字符或以 开头的任意数据-)
请注意,$*参数扩展的形式(仅用于引用)是用于连接位置参数($IFS默认为, SPC的第一个字符)的形式。您需要$@(再次引用)将所有位置参数扩展为分隔参数。未加引号,$*并且$@没有什么意义(除非zsh它们扩展到非空的位置参数),因为它们会受到 split+glob 的影响,并且行为因壳而异。
#!/bin/bash
echo $*
FIELDS=("${@/#/x}")
FIELDS=("${FIELDS[@]/%/y}")
echo "${FIELDS[*]}"
Run Code Online (Sandbox Code Playgroud)
运行时:
$ t.sh foo bar baz
foo bar baz
xfooy xbary xbazy
Run Code Online (Sandbox Code Playgroud)