You are not logged in.

#1 2013-11-15 15:23:08

ninian
Member
From: United Kingdom
Registered: 2008-02-24
Posts: 726
Website

How to use sed on a literal string containing regex meta characters?

I want to delete the lines from a file which match an arbitrary literal string.
The string is contained in a variable, and may itself contain various regex meta characters such as [,],^,$,|, etc
So, my problem is that sed wants to interpret these meta characters itself. For example:

x='abc[xyz$'
sed -i "/$x/d" file

produces a sed error about the unmatched [, and no doubt it wants to interpret the $ too.
(Of course, I could try and change the string $x so that every possible regex meta character was escaped with a \, but that seems immensely cumbersome. Also, can't see a way of using single or double quotes cleverly.)

Sorry if I am being thick about this, but any ideas or alternative methods would be most welcome!

Offline

#2 2013-11-15 15:45:55

frostschutz
Member
Registered: 2013-11-15
Posts: 1,496

Re: How to use sed on a literal string containing regex meta characters?

With sed, you have to escape meta characters indivudually. That's just how it works. Of course you could do the escaping using sed as well, by replacing all meta characters (including \ and /) with \character.

If you want to match strings literally, use a different tool. Or do it in Bash.

while read line
do
    [ "$line" != "$x" ] && echo "$line"
done < file

In Perl/PCRE instead of escaping indivudually there is \Q...\E but sed does not understand that, and \Q\E does not solve all problems either, if there is a \E in the $x you have to escape it with \E\\E\Q or something like it.

Last edited by frostschutz (2013-11-15 15:46:42)

Offline

#3 2013-11-15 15:52:38

ninian
Member
From: United Kingdom
Registered: 2008-02-24
Posts: 726
Website

Re: How to use sed on a literal string containing regex meta characters?

frostschutz wrote:

With sed, you have to escape meta characters indivudually. That's just how it works. Of course you could do the escaping using sed as well, by replacing all meta characters (including \ and /) with \character.

If you want to match strings literally, use a different tool. Or do it in Bash.

while read line
do
    [ "$line" != "$x" ] && echo "$line"
done < file

In Perl/PCRE instead of escaping indivudually there is \Q...\E but sed does not understand that, and \Q\E does not solve all problems either, if there is a \E in the $x you have to escape it with \E\\E\Q or something like it.

Thank you for your swift reply. Looks like sed can't be much of a friend in these circumstances!
Probably will have to go with the Bash file handling method.
Oh well ...

Offline

#4 2013-11-15 18:57:23

moetunes
Member
From: A comfortable couch
Registered: 2010-10-09
Posts: 1,033

Re: How to use sed on a literal string containing regex meta characters?

Using quotes differently

sed -i '/"$x"/d' file

stops sed from erroring out.


You're just jealous because the voices only talk to me.

Offline

#5 2013-11-15 19:04:07

frostschutz
Member
Registered: 2013-11-15
Posts: 1,496

Re: How to use sed on a literal string containing regex meta characters?

moetunes wrote:

Using quotes differently

sed -i '/"$x"/d' file

stops sed from erroring out.

Certainly. It also stops sed from doing what the OP wanted. In particular, it probably does nothing.

Offline

#6 2013-11-16 01:29:29

zorro
Member
Registered: 2011-11-18
Posts: 47

Re: How to use sed on a literal string containing regex meta characters?

You could automatically escape the meta characters

x='abc[xyz$'
echo $x | sed 's/\([[$]\)/\\\1/g'

generates: abc\[xyz\$

This can then be processed by sed

sed "/$(echo $x | sed 's/\([[$]\)/\\\1/g')/d"

Offline

#7 2013-11-16 01:39:40

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,332
Website

Re: How to use sed on a literal string containing regex meta characters?

Would grep be an option?  It would do exactly what was requested:

grep -Fv "$x" file

"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#8 2013-11-16 11:47:56

ninian
Member
From: United Kingdom
Registered: 2008-02-24
Posts: 726
Website

Re: How to use sed on a literal string containing regex meta characters?

zorro wrote:

You could automatically escape the meta characters

x='abc[xyz$'
echo $x | sed 's/\([[$]\)/\\\1/g'

generates: abc\[xyz\$

This can then be processed by sed

sed "/$(echo $x | sed 's/\([[$]\)/\\\1/g')/d"

Thank you zorro, yes I can see that will work, if I extend it to escape all 12 (?) regex metachars.
Also, to cope with embedded spaces and match whole lines in the file, I've tweaked your expression thus:

sed "/^$(echo "$x" | sed 's/\([[$]\)/\\\1/g')$/d"

wink

Offline

#9 2013-11-16 11:59:29

ninian
Member
From: United Kingdom
Registered: 2008-02-24
Posts: 726
Website

Re: How to use sed on a literal string containing regex meta characters?

Trilby wrote:

Would grep be an option?  It would do exactly what was requested:

grep -Fv "$x" file

Of course, of course, I forgot all about grep's -F option! sed is not sacred ...
I just need to add the -x option to match whole lines and rewrite the file after deleting the lines:

grep -Fvx "$x" file >file.$$; mv file.$$ file

Thank you Trilby!

Offline

Board footer

Powered by FluxBB