我对 bash 及其正则表达式匹配能力有一个问题,我现在认为这是 bash 中的一个错误,但也可能是我错过了一些明显的东西。我希望是后者。
我在 bash 脚本中创建了这个函数,将地址溢出到字段中。有一些调试输出最终将被删除:
# name number, zip
function split_address
{
local adr
adr="$4"
echo $adr
local adr_regex
adr_regex="[ ]*(.*[a-z ]) ([^,][^,]*),[ ]*([^ ]*)[ ]*"
[[ $adr =~ $adr_regex ]]
echo 1:X${BASH_REMATCH[1]}X
echo 2:X${BASH_REMATCH[1]%% }X
echo 3:Y${BASH_REMATCH[2]}Y
echo 4:Y${BASH_REMATCH[2]%% }Y
local x="${BASH_REMATCH[1]}"
echo 5:X${x%% }X
local x="${BASH_REMATCH[1]%% }"
echo 6:X${x}X
echo 7:X${x%% }X
eval "$1='${BASH_REMATCH[1]%% }'"
eval "$2='${BASH_REMATCH[2]%% }'"
eval "$3='${BASH_REMATCH[3]}'"
}
我这样测试:
split_address roadname number zip " Some string 42 dp , 1234 "
echo X${roadname}X Y${number}Y Z${zip}Z
当调用时,我得到以下输出:
Some string 42 dp , 1234
1:XSome string X
2:XSome string X
3:Y42 dp Y
4:Y42 dpY
5:XSome string X
6:XSome string X
7:XSome stringX
XSome string X Y42 dpY Z1234Z
首先请注意,4 已删除 3 中所示的空格。这就是我在处理 1 时希望在 2 中发生的情况。请注意,即使这发生在变量 x 上,5 也不会删除空格。这是解决此问题的尝试。然后我尝试将空格删除操作分配给变量 x,但也失败了(如图 6 所示)。但是在步骤 7 中删除 x 上的空格是有效的,即使该行与 5 相同并且输入显然也是如此。
这是我在做一些奇怪的事情还是 bash 中的错误?
作为参考,我正在使用 bash 版本 4.3.11(1)-release 的 Ubuntu 14 LTS。
我在 bash 版本 4.1.17(9-release.x) 的 Cygwin-x64 上看到了相同的行为。
我已经验证要删除的字符确实是一个空格(在源和测试调用上都使用 od )。
答案1
%%
做全局匹配,不匹配正则表达式。这意味着${foo%% }
将删除匹配 a 的最长尾随字符串单身的空格字符,当然只是一个空格字符,并且${foo%% *}
将删除最长的尾随字符串开始带有空格字符。
awk
使用将字符串拆分为字段可能会更好。
答案2
按照给出的解决方案https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-bash-variable我这样修复了我的脚本:
echo "8:X${BASH_REMATCH[1]%"${BASH_REMATCH[1]##*[![:space:]]}"}X"
eval "$1='${BASH_REMATCH[1]%"${BASH_REMATCH[1]##*[![:space:]]}"}'"
这是一个双字符串操作,第一个/内部部分删除除尾随空格之外的所有内容。然后使用该字符串截掉原始字符串末尾的相同空格。