I have a string and I need to add #
, in the beginning,i.e. convert [ -n "$ID" -a "$ID" -le 200 ] && return
to #[ -n "$ID" -a "$ID" -le 200 ] && return
. I can use below command:
echo '[ -n "$ID" -a "$ID" -le 200 ] && return'| sed -n -e 's/\[ -n "$ID" -a "$ID" -le 200 \] && return/#&/p'
It works. Now I have two questions, regarding E
, flag.
For the string [ -n "$ID" -a "$ID" -le 200 ]
, if I escape brackets, it does not work; however, it works when I do not escape them i.e.
sed -n -E 's/[ -n "$ID" -a "$ID" -le 200 ]/#&/p'
works while
sed -n -E 's/\[ -n "$ID" -a "$ID" -le 200 \]/#&/p'
doesn't work.
For, the full string [ -n "$ID" -a "$ID" -le 200 ] && return
, it gives me wrong answer, when I do not escape them:
echo '[ -n "$ID" -a "$ID" -le 200 ] && return'| sed -n -E 's/[ -n "$ID" -a "$ID" -le 200 ] && return/#&/p'
It gives me output:
[ -n "$ID" -a "$ID" -le 200 #] && return
I want to know how it is working.
sed -n -E 's/[ -n "$ID" -a "$ID" -le 200 ]/#&/p'
Does not work the way you expect it to work, it's more of a coincidence: [...]
is a collection of characters that match. Inside that collection you have a range -n
from whitespace (0x20) to n
(0x6E), which can include [
(0x5B), depending on your locale settings. So the collection matches the first char. See what happens when you take #&___
as the replacement... not your intention, I guess?
And that's the reason for your full case to fail: The matching character for the collection is the ]
because it is followed by the rest of the pattern, that's why the #
is inserted there.
The problem with the extended regular expression is like @steeldriver assumed: The $
anchors the pattern:
A ( '$' ) outside a bracket expression shall anchor the expression or subexpression it ends to the end of a string; such an expression or subexpression can match only a sequence ending at the last character of a string. For example, the EREs "ef$" and "(ef$)" match "ef" in the string "abcdef", but fail to match in the string "cdefab", and the ERE "e$f" is valid, but can never match because the 'f' prevents the expression "e$" from matching ending at the last character.
So in ERE, a literal $
needs to be escaped, while in BRE it only needs to be escaped when being the last character of the pattern.
Also note that -e
marks the next argument as a script and is optional if there is only one script, while -E
is a switch. Dropping -e
for '-E` only works if there is only one script because it was superfluous anyhow.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments