bev*_*bev 5 bash regular-expression
我有一个包含在变量中的字符串,我想根据相对于另一个子字符串的位置提取子字符串。除非将字符串作为 arg 发送到函数,否则我的解决方案似乎有效。我正在使用 bash shell。
#!/usr/bin/bash
var0="-a check one two three"
var1="check"
function getsubstr() {
echo ${*#*"${2}"}
}
# this prints 'one two three' which is what I want
echo ${var0#*"${var1}"}
# this prints '-a one two three', not what I want.
getsubstr $var0
Run Code Online (Sandbox Code Playgroud)
请注意,当我放入echo $*
该getsubstr
函数时,它会打印与$var0
(-> '-a check one two Three')相同的字符串,而当我放入echo $2
该getsubstr
函数时,它会打印与$var1
(-> 'check')相同的字符串。因此,在我看来,我要求在两种情况下都打印相同的子字符串。
另一个难题是,如果不是echo ${*#*"${2}"}
在getsubstr
我使用的函数中echo ${*%"${2}"*}
,而是得到完全相同的结果。
任何帮助理解这种行为将不胜感激。
顺便说一句,我意识到 ${*:3}
在getsubstr
函数内部可以返回我想要的子字符串,但我试图理解#*<regexp>
和%<regextp>*
行为。
您getsubstr $var0
正在将 5 个参数传递给函数。
此外,$* 和 $@ 测试每个单独的$1 $2 等等。 arg 针对#模式。
关于 RegEx in bash
:我在最后添加了一些示例,顺便说一句,'*'在正则表达式上下文中使用时只是一个特殊的正则表达式字符,即。使用时 =~。在您第一次使用 * in 时${*
,星号的特殊用途是作为var的(伪)名称,它扩展为所有 var 的串联: $1 $2 $...etc...
您第二次使用星号,in #*"${2}"
, 意味着“$2”前面有任何东西,包括 nothing,将分别/单独地与每个传递的 $1 等 arg 匹配。
以下脚本可能有助于 $@ 和 $* (通过示例)...
#!/bin/bash
#
getsubstr() {
echo -n " ${#@} args";
[[ "$1$2$3$4$5$6" == *\ * ]] && echo " (with embedded spaces)" || echo " (no spaces)"
echo ' "${*}" '\|"${*}"\|
echo ' ${*} '\|${*}\|
echo ' "${@}" '\|"${@}"\|
echo ' ${@} '\|${@}\|
echo ' "${*#*"${2}}" '\|"${*#*"${2}"}"\|
echo ' ${*#*"${2}} '\|${*#*"${2}"}\|
echo ' "${@#*"${2}}" '\|"${@#*"${2}"}"\|
echo ' ${@#*"${2}} '\|${@#*"${2}"}\|
echo ' ${*#B} '\|${*#B}\|
echo ' "${*#B}" '\|"${*#B}"\|
echo ' ${@#B} '\|${@#B}\|
echo ' "${@#B}" '\|"${@#B}"\|
}
var0="a B c "
echo
echo -n "Passing "; getsubstr "$var0" ; echo
echo -n "Passing "; getsubstr $var0 ; echo
echo -n "Passing "; getsubstr "$var0" "$var0" ; echo
echo -n "Passing "; getsubstr $var0 $var0 ; echo
echo
exit
###################################################################
Run Code Online (Sandbox Code Playgroud)
正则表达式 bash
# Regex checks: "=~" uses extended regular expression
#+ Parenthesized subexpressions within the regular expression are saved
#+ in the array variable BASH_REMATCH
#+ $BASH_REMATCH / ${BASH_REMATCH[0]} is the string matching the entire regular expression.
#+ ${BASH_REMATCH[n]} is the sub string matching the nth parenthesized subexpression
[[ "abcdef" =~ (.)(.)(.) ]] && echo "# $BASH_REMATCH"
# abc
[[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[0]}"
# abc
[[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[2]}"
# b
[[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[@]}"
# abc a b c
Run Code Online (Sandbox Code Playgroud)