2

我有一个变量,其中包含四个用空格分隔的数字,例如:

a="12.3 423.4 11.0033 14.02"

但有时,我有一个尾随空格:

a="12.3 423.4 11.0033 14.02 "

我想用“&”替换空格,为此,我这样做:

echo ${a// / & }

这给了我:

12.3 & 423.4 & 11.0033 & 14.02

或者如果我有一个尾随空格:

12.3 & 423.4 & 11.0033 & 14.02 & 

我的问题是我不知道我的字符串末尾是否会有一个空格,而且无论如何我都不想要那个额外的“&”。避免这个额外字符的最优雅的方法是什么?有没有办法说“如果空格和下一个字符是数字则替换”?

编辑:我知道我可以使用 sed,但由于 bash 中有变量替换机制,我想知道如何使用它来做我想做的事。我不知道如何在 bash 替换中写“不是行尾”或“是数字”。

4

5 回答 5

8

如果有的话,这将删除尾随空格:

a=${a% }

然后你可以做你的替换:

a=${a// / & }
于 2013-09-27T13:55:17.527 回答
1

您可以使用 sed 并捕获匹配项。

$ echo 12.3 423.4 11.0033 14.02 | sed 's/ [0-9]/ \&&/g'
12.3 & 423.4 & 11.0033 & 14.02

因此,/ [0-9]/您只需替换有空格后跟数字的地方。

如果您不想使用 sed,您可以检查下一个字符是否 EOL。

${a// [^$]/ & }
于 2013-09-27T13:50:12.933 回答
1
shopt -s extglob            # enable extended globbing patterns
b=${a/%+([[:blank:]])/}     # remove trailing whitespace
b=${b/#+([[:blank:]])/}     # remove leading whitespace
b=${b//+([[:blank:]])/ & }  # globally replace whitespace by " & "
echo ">$a<"
echo ">$b<"
>12.3 423.4 11.0033 14.02 <
>12.3 & 423.4 & 11.0033 & 14.02<

参考:

http://www.gnu.org/software/bash/manual/bashref.html#Pattern-Matching
http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion

于 2013-09-27T14:24:25.607 回答
1

这可能是一种人为的方法,但是 FWIW。如果您可以将多个连续的空格替换为单个&,则可以使用 bashreadprintf内置函数将字符串拆分为一个数组(假设IFS拆分的默认空格),然后使用临时IFS的重新加入&,见下文。

a="12.3 423.4 11.0033 14.02 "
read -r -a x <<< "${a}"
IFS='&' eval 'printf -v a "%s" "${x[*]}"'
echo $a
12.3&423.4&11.0033&14.02
于 2013-09-27T14:31:15.087 回答
0

也许你可以做

a=`echo "12.3 423.4 11.0033 14.02 " | sed 's/ *$//'`
echo ${a// / & }

这样您就可以删除尾随空格。

于 2013-09-27T13:44:43.383 回答