![与 bash 中的 Make 中的addsuffix/addprefix 等效操作](https://linux22.com/image/209746/%E4%B8%8E%20bash%20%E4%B8%AD%E7%9A%84%20Make%20%E4%B8%AD%E7%9A%84addsuffix%2Faddprefix%20%E7%AD%89%E6%95%88%E6%93%8D%E4%BD%9C.png)
给定一个以空格分隔的单词列表,如何在不执行任何外部命令的情况下为所有单词添加前缀(或后缀)?
Make 有这样的构造:
$(addprefix foo,bar baz)
⇒ foobar foobaz
答案1
使用 bash 5.2(目前处于测试版)或更高版本,您可以执行以下操作:
bash-5.2$ shopt -s extglob patsub_replacement
bash-5.2$ string='foo bar baz'
bash-5.2$ printf '%s\n' "${string//+([^ ])/&suffix}"
foosuffix barsuffix bazsuffix
相当于 ksh93 的:
printf '%s\n' "${string//+([^ ])/\0suffix}"
或者 的zsh
:
set -o extendedglob
printf '%s\n' "${string//(#m)([^ ])##/${MATCH}suffix}"
答案2
您可以使用shell参数扩展在数组的元素上。将空格分隔的列表转换为数组:
a=(bar baz bat)
然后展开它,用您的前缀“替换”每个项目的开头:
printf "%s " "${a[@]/#/foo}"
您可以使用以下方式以相同的方式添加后缀%
:
printf "%s " "${a[@]/%/foo}"
您还可以对以空格分隔的单词使用 shell 参数扩展(如果这些单词由单个空格分隔),只需两个步骤:
w="bar baz bat"
r="${w/#/foo}"
r="${r// / foo}"
(IE将字符串的开头替换为前缀,并将任何空格替换为空格后跟前缀)。
如果extglob
shopt
启用,这也可以处理重复的空格:
w="bar baz bat"
r="${w/#/foo}"
r="${r//+( )/ foo}"
答案3
对于以空格分隔的字符串来说是不可能的,但是对于数组来说是可能的。您可以将空格分隔的字符串转换为数组。
以带有空格分隔的单词的变量开头:
words="foo bar baz"
将其转换为数组:
array=($words)
并添加后缀:
echo -- "${array[@]/%/suffix}"
⇒ foosuffix barsuffix bazsuffix
或者添加前缀:
echo -- "${array[@]/#/prefix}"
⇒ prefixfoo prefixbar prefixbaz
重复添加前缀和后缀。