我无法弄清楚如何在bash变量中替换逗号后跟0或更多空格。这就是我所拥有的:
base="test00 test01 test02 test03"
options="test04,test05, test06"
for b in $(echo $options | sed "s/, \+/ /g")
do
base="${base} $b"
done
我想做的是附加"选项"到了"基地"。选项是用户输入,可以是空的或csv列表,但该列表可以是
" test04,test05,test06" - >逗号后面的空格
" test04,TEST05,test06" - >没有空格
" test04,test05,test06" - >混合物
我需要的是我的输出" base"是一个空格分隔列表,但无论我尝试什么我的列表在第一个单词后不断被切断。
我的预期是
" test00 test01 test02 test03 test04 test05 test06"
答案 0 :(得分:6)
如果您的目标是生成命令,则此技术完全错误:如BashFAQ #50中所述,命令参数应存储在数组中,而不是以空格分隔的字符串。
base=( test00 test01 test02 test03 )
IFS=', ' read -r -a options_array <<<"$options"
# ...and, to execute the result:
"${base[@]}" "${options_array[@]}"
尽管如此,即使这对于许多合法用例也是不够的:考虑如果要传递包含文字空格的选项会发生什么 - 例如,运行./your-base-command "base argument with spaces" "second base argument" "option with spaces" "option with spaces" "second option with spaces"
。为此,您需要以下内容:
base=( ./your-base-command "base argument with spaces" "second base argument" )
options="option with spaces, second option with spaces"
# read options into an array, splitting on commas
IFS=, read -r -a options_array <<<"$options"
# trim leading and trailing spaces from array elements
options_array=( "${options_array[@]% }" )
options_array=( "${options_array[@]# }" )
# ...and, to execute the result:
"${base[@]}" "${options_array[@]}"
答案 1 :(得分:4)
不需要sed,bash内置了模式替换parameter expansion。使用bash 3.0或更高版本,extglob
添加了对更高级regular expressions的支持。
# Enables extended regular expressions for +(pattern)
shopt -s extglob
# Replaces all comma-space runs with just a single space
options="${options//,+( )/ }"
如果你没有bash 3.0+可用或者不想启用extglob
,只需删除所有可以在大部分时间工作的空格:
# Remove all spaces
options="${options// /}"
# Then replace commas with spaces
options="${options//,/ }"