linux Bash:仅使用参数扩展查找和替换

y3bcpkx1  于 2023-03-22  发布在  Linux
关注(0)|答案(4)|浏览(133)

我想替换输入,

input_string: @include circle-progress(38px, 30px, #4eb630)

和输出,

Output_string: @include circle-progress(38px, 30px)

使用${input_string//pattern/replacement_string},其中模式为, #[A-Fa-f0-9]{3,6} I电源。
这个模式与我在www.example.com中测试时想要替换的部分相匹配regex101.com,但是代码

replace_pat=", \#[A-Fa-f0-9]{3,6}"
echo "${input_string//"$replace_pat"/}"

输出完全相同的输入。我不想使用任何类似sed的东西。不知道我哪里出错了。

waxmsbnn

waxmsbnn1#

你用的模式替换(${var//pattern/replacement})使用glob patterns,而不是正则表达式。Glob模式的功能明显不如正则表达式(并且有非常不同的语法),所以你不能完全做到你想做的。(而不是一个通用的POSIX shell)并启用扩展的glob模式。它们的语法与正则表达式非常不同,但它们实际上同样强大(但有时并不优雅)。

shopt -s extglob    # Enable extended glob pattern syntax
replace_glob=', #[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?([A-Fa-f0-9]?([A-Fa-f0-9]?([A-Fa-f0-9])))'
input_string='@include circle-progress(38px, 30px, #4eb630)'
echo "${input_string//$replace_glob/}"    # prints "@include circle-progress(38px, 30px)"

我有没有提到扩展的globs可能不优雅?它们在有界重复时尤其糟糕(正则表达式中的{3,6},表示前一项的3到6之间)。上面的glob以“,#”开头。”[10]“三”“三”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一”“一然后是可选的(由?( )表示)模式,它包括另一个十六进制数字和一个可选字符串,好吧,你明白了。如果你想简化它,只允许任何数量的十六进制数字,那么事情就简单多了

replace_glob=', #*([A-Fa-f0-9])'

(BTW,还请注意,我在使用模式变量时没有用双引号引起来--这是因为shell将引用的模式(或模式的一部分)视为文字字符串,而忽略了glob语法。这是shell中少数几种不应该用双引号引变量引用的情况之一。)

bgtovc5b

bgtovc5b2#

[root@XXX ~]# a="@include circle-progress(38px, 30px**, #4eb630**)"; echo $a | sed 's/\*\*,.*/)/g'
@include circle-progress(38px, 30px)
mjqavswn

mjqavswn3#

您可以用途:

str='input_string: @include circle-progress(38px, 30px, #4eb630)'; echo ${str/, #[A-Fa-f0-9]*/)}

或者使用sed:

echo 'input_string: @include circle-progress(38px, 30px, #4eb630)' | sed 's/, #[A-Fa-f0-9]\{3,6\}//'
5anewei6

5anewei64#

以下内容最初是OP添加到问题中的自我回答。

解决.谢谢你戈登.

使用glob模式的解决方案工作得很好,但是现在下面的代码仍然打印出完全相同的输入,即当我从文件中读取代码行时,line匹配pattern

pattern="@include circle-progress\(([0-9]{1,3}px, ){2}#[A-Fa-f0-9]{3,6}\)"
replace_glob=', #[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?([A-Fa-f0-9]?([A-Fa-f0-9]?([A-Fa-f0-9])))'
while IFS='' read -r line || [[ -n "$line" ]]; do
    if [[ $line =~ $pattern ]] 
    then
        echo "${line//$replace_glob/}" 
    fi
done < "$1"

相关问题