2012-10-10 52 views
1

我有这个字符串:如何选择替代空间与猛砸字符串只

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来做到这一点。

+0

在这里看到我的回答 - HTTP:// stackoverflow.com/questions/12821302/split-a-string-only-by-spaces-that-are-outside-quotes - 它确实是你要求 – 2012-10-10 21:27:57

回答

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

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

+1

请看OP,没有awk,'var'也可能会丢失,也可能有双引号或单引号 –

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"