如何选择性地仅使用Bash替换字符串中的空格

时间:2012-10-10 12:51:27

标签: bash

我有这个字符串:

str='1 2 3 var="foo bar" 4 5 6'

也可能是这样的:

str="1 2 3 var='foo bar' 4 5 6"

如何仅在引号(双引号或单引号)内用+替换空格?

结果应该是:

1 2 3 var="foo+bar" 4 5 6

1 2 3 var='foo+bar' 4 5 6

如果var是单引号。

var可以是任何东西,它不是强匹配。 它也可能完全缺失,如下所示:

str='1 2 3 "foo bar" 4 5 6'

我不想使用awk,sed或perl来执行此操作。

3 个答案:

答案 0 :(得分:3)

逐个字符循环字符串。保持一个标志,告诉你是否在引号内。根据标志,在需要时替换空格:

#! /bin/bash
str='1 2 3 var="foo bar" 4 5 6'

result=''
inside=0
for (( i=0 ; i<${#str} ; i++ )) ; do
    char=${str:i:1}
    if [[ $char == [\"\'] ]] ; then
        let inside=!inside
    fi
    (( inside )) && char=${char/ /+}
    result+=$char
done
echo $result

答案 1 :(得分:0)

$ echo $str | awk -F= '{sub(/ /,"+",$2);}1' OFS="="
1 2 3 var='foo+bar' 4 5 6

使用awk,仅在第二个字段中用+替换空格(第二个字段恰好是用=分隔时的表达式。)

答案 2 :(得分:0)

这与choroba的答案相同,只是使用不同的技术来迭代字符串:

#!/bin/bash

str='1 2 3 var="foo bar" 4 5 6'
result=''
declare -i inside=0
while IFS= read -n1 char; do
    [[ $char = [\"\'] ]] && inside=!inside
    (( inside )) && char=${char/ /+}
    result+=$char
done <<< "$str"
echo "$result"