如何使用sed替换bash中后跟0或更多空格的命令

时间:2016-09-01 16:25:30

标签: linux bash sed

我无法弄清楚如何在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"

2 个答案:

答案 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//,/ }"