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

时间:2017-12-21 08:11:15

标签: linux bash scripting

我想替换输入,

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}

当我在regex101.com中测试时,此模式与我想要替换的部分相匹配,但是代码

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

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

解决即可。谢谢戈登。

具有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"

3 个答案:

答案 0 :(得分:2)

您正在使用的模式替换(${var//pattern/replacement})使用glob patterns,而不是正则表达式。 Glob模式的强大程度远远低于正则表达式(并且语法有很大不同),因此您无法完全按照自己的意愿行事。好吧,除非您使用bash(不是通用的POSIX shell)并启用扩展的glob模式。它们的语法与正则表达式有很大的不同,但它们实际上同样强大(但有时不优雅)。以下是如何在bash中执行此操作:

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)"

我是否提到延长的球可能不够优雅?他们在有限重复时特别糟糕(正则表达式中的{3,6},意思是前一项的3到6之间)。上面的glob以&#34;,#&#34;开头。 (显然),然后三个&#34; [A-Fa-f0-9]&#34;&#39; s,然后是一个可选的(由?( )表示)模式,包括另一个十六进制数字和一个可选项字符串......好吧,你明白了。如果你想简化它并只允许任意数量的十六进制数字,那么它会变得更简单:

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

(顺便说一下,还要注意我在使用时没有对模式变量进行双重引用 - 这是因为shell将引用的模式(或模式的一部分)视为文字字符串,其中是glob语法被忽略。这是shell中少数情况之一,你不应该双引号变量引用。)

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您可以使用:

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\}//'