我想使用bash操作符+~首先拆分一个字符串,然后再次检查得到的字符串。当我尝试这样做时,如果发现BASH_REMATCH的元素被第二种用法覆盖,那么母函数在第二次使用时就会失败。
例如,以下构造的示例:
#!/bin/bash
inputline="abc123ABC123abc,xyz890XYZ890xyz"
checkABC ()
{
local teststring="$1"
local pattern="([^,]+),(.*)"
if [[ $teststring =~ $pattern ]]; then
echo "${BASH_REMATCH[1]}; ${BASH_REMATCH[2]}"
checkNum ${BASH_REMATCH[1]}
checkNum ${BASH_REMATCH[2]}
fi
}
checkNum ()
{
if [[ $1 =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]; then
echo "${BASH_REMATCH[1]}; ${BASH_REMATCH[2]}"
fi
}
set -x
checkABC $inputline这将给出以下输出,我们可以看到${BASH_REMATCH[2]}是如何被函数checkNum覆盖的。
$ bash ./leaking.sh
+ checkABC abc123ABC123abc,xyz890XYZ890xyz
+ local teststring=abc123ABC123abc,xyz890XYZ890xyz
+ local 'pattern=([^,]+),(.*)'
+ [[ abc123ABC123abc,xyz890XYZ890xyz =~ ([^,]+),(.*) ]]
+ echo 'abc123ABC123abc; xyz890XYZ890xyz'
abc123ABC123abc; xyz890XYZ890xyz
+ checkNum abc123ABC123abc
+ [[ abc123ABC123abc =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]
+ echo '123; 123'
123; 123
+ checkNum 123
+ [[ 123 =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]我知道,我可以通过将重匹配的结果复制到另一个数组来防止这种情况,我可以在这个数组上进行本地处理并应用checkNum (参见下面的示例)。这是一种智能的方法吗,还是有更好的方法来防止从函数中泄漏?
这段代码
#!/bin/bash
inputline="abc123ABC123abc,xyz890XYZ890xyz"
checkABC ()
{
local teststring="$1"
local pattern="([^,]+),(.*)"
local -a storeRematch
if [[ $teststring =~ $pattern ]]; then
storeRematch=("${BASH_REMATCH[@]}")
echo "${storeRematch[1]}; ${storeRematch[2]}"
checkNum ${storeRematch[1]}
checkNum ${storeRematch[2]}
fi
}
checkNum ()
{
if [[ $1 =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]; then
echo "${BASH_REMATCH[1]}; ${BASH_REMATCH[2]}"
fi
}
set -x
checkABC $inputline按我希望的方式执行:
bash ./notleaking.sh
+ checkABC abc123ABC123abc,xyz890XYZ890xyz
+ local teststring=abc123ABC123abc,xyz890XYZ890xyz
+ local 'pattern=([^,]+),(.*)'
+ local -a storeRematch
+ [[ abc123ABC123abc,xyz890XYZ890xyz =~ ([^,]+),(.*) ]]
+ storeRematch=("${BASH_REMATCH[@]}")
+ echo 'abc123ABC123abc; xyz890XYZ890xyz'
abc123ABC123abc; xyz890XYZ890xyz
+ checkNum abc123ABC123abc
+ [[ abc123ABC123abc =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]
+ echo '123; 123'
123; 123
+ checkNum xyz890XYZ890xyz
+ [[ xyz890XYZ890xyz =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]
+ echo '890; 890'
890; 890发布于 2016-06-07 09:24:21
有点麻烦,但由于它只是当前shell的本地版本,所以您可以在函数中运行子shell。
checkNum ()
{
(
if [[ $1 =~ [a-z]+([0-9]+)[A-Z]+([0-9]+)[a-z]+ ]]; then
echo "${BASH_REMATCH[1]}; ${BASH_REMATCH[2]}"
fi
)
}或
(
checkNum ${BASH_REMATCH[1]}
checkNum ${BASH_REMATCH[2]}
)这将防止BASH_REMATCH对这两个函数都是全局的。
除此之外,我认为将它分配给另一个数组是最好的(事实上,它不会打开一个新的进程/子subshell)。
发布于 2016-06-07 09:20:55
BASH_REMATCH是一个只读变量,所以像local BASH_REMATCH这样的东西不能工作。
根据您的建议,您可以将结果复制到另一个变量:
local re
re=("${BASH_REMATCH[@]}")在你的例子中--我想提一提--你可以用:
# teststring="1234,5678"
checkNum "${teststring%%,*}" # 1234
checkNum "${teststring#*,}" # 5678https://stackoverflow.com/questions/37674871
复制相似问题