Is there some way to replace a string such as @
or *
or ?
or &
without needing to put a "\" before it?
Example:
perl -pe 'next if /^#/; s/\@d\&/new_value/ if /param5/' test
In this example I need to replace a @d&
with new_value
but the old value might contain any character, how do I escape only the characters that need to be escaped?
The backslash is the escape character and is used to make use of escape sequences. When there is a need to insert the escape character in an interpolated string, the same backslash is used, to escape the substitution of escape character with ” (blank). This allows the use of escape character in the interpolated string.
This works because in Perl, the s/.../.../ notation supports backslash-escapes. \x27 is a hexadecimal escape ( ' being U+0027). Show activity on this post. This ends the quoted part, escapes a single quote as it would appear outside of quotes, and then begins the quoting again.
As discussed at perldoc perlre:
...Today it is more common to use the quotemeta() function or the "\Q" metaquoting escape sequence to disable all metacharacters' special meanings like this:
/$unquoted\Q$quoted\E$unquoted/
Beware that if you put literal backslashes (those not inside interpolated variables) between "\Q" and "\E", double-quotish backslash interpolation may lead to confusing results. If you need to use literal backslashes within "\Q...\E", consult "Gory details of parsing quoted constructs" in perlop.
You can also use a '
as the delimiter in the s/// operation to make everything be parsed literally:
my $text = '@';
$text =~ s'@'1';
print $text;
In your example, you can do (note the single quotes):
perl -pe 's/\b\Q@f&\E\b/new_value/g if m/param5/ and not /^ *#/'
You have several problems:
\b
incorrectlyFrom perldoc perlre
A word boundary ("\b") is a spot between two characters that has a "\w" on one side of it
Neither of the characters @
or &
are \w
characters. So your match is guaranteed to fail. You may want to use something like s/(^|\s)\@d\&(\s|$)/${1}new text$2/
(^|\s)
says to match either the start of the string (^
)or a whitespace character (\s
).
(\s|$)
says to match either the end of the string ($
) or a whitespace character (\s
).
To solve the second problem, you should use %ENV
.
To solve the third problem, you should use the \Q
and \E
escape sequences to escape the value in $ENV{a}
.
Putting it all together we get:
#!/bin/bash
export a='@d&'
export b='new text'
echo 'param5 @d&' |
perl -pe 'next if /^#/; s/(^|\s)\Q$ENV{a}\E(\s|$)/$1$ENV{b}$2/ if /param5/'
Which prints
param5 new text
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With