Reputation: 786
I want to replace the input,
input_string: @include circle-progress(38px, 30px, #4eb630)
and output,
Output_string: @include circle-progress(38px, 30px)
using ${input_string//pattern/replacement_string}
where pattern is , #[A-Fa-f0-9]{3,6}
I supply.
This pattern matches the portion I want to replace when I test it in regex101.com, but the code
replace_pat=", \#[A-Fa-f0-9]{3,6}"
echo "${input_string//"$replace_pat"/}"
outputs exactly the same input. I don't want to use anything else like sed. Don't know where I am going wrong.
Upvotes: 1
Views: 1403
Reputation: 295291
The below was originally a self-answer added to the question by the OP.
SOLVED. Thank You Gordon.
The solution with glob patterns works perfectly, but now the code below still prints exactly the same input i.e the line
matching pattern
, when I read lines of code from a file.
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"
Upvotes: 0
Reputation: 125708
The pattern replacement you're using (${var//pattern/replacement}
) uses glob patterns, not regular expressions. Glob patterns are significantly less powerful than regular expressions (and have very different syntax), so you can't entirely do what you're trying to. Well, unless you're using bash (not a generic POSIX shell) and enable extended glob patterns. Their syntax is very different from regular expressions, but they're actually just as powerful (but sometimes inelegant). Here's how to do this in 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)"
Did I mention that extended globs can be inelegant? They're especially bad at bounded repetitions (the {3,6}
in the regular expression, meaning between 3 and 6 of the preceding item). The glob above starts with ", #" (obvious), then three "[A-Fa-f0-9]"'s, then an optional (indicated by ?( )
) pattern that includes another hex digit and an optional string that... well, you get the idea. If you want to simplify it and just allow any number of hex digits, then it gets much simpler:
replace_glob=', #*([A-Fa-f0-9])'
(BTW, also note that I didn't double-quote the pattern variable when using it -- that's because the shell treats quoted patterns (or parts of patterns) as literal strings, where the glob syntax is ignored. This is one of the few cases in the shell where you shouldn't double-quote variable references.)
Upvotes: 3
Reputation: 13239
You could use:
str='input_string: @include circle-progress(38px, 30px, #4eb630)'; echo ${str/, #[A-Fa-f0-9]*/)}
or with sed:
echo 'input_string: @include circle-progress(38px, 30px, #4eb630)' | sed 's/, #[A-Fa-f0-9]\{3,6\}//'
Upvotes: 0
Reputation: 1838
[root@XXX ~]# a="@include circle-progress(38px, 30px**, #4eb630**)"; echo $a | sed 's/\*\*,.*/)/g'
@include circle-progress(38px, 30px)
Upvotes: 0