与 bash 中的 Make 中的addsuffix/addprefix 等效操作

与 bash 中的 Make 中的addsuffix/addprefix 等效操作

给定一个以空格分隔的单词列表,如何在不执行任何外部命令的情况下为所有单词添加前缀(或后缀)?

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

重复添加前缀和后缀。

相关内容