|
From: Julian S. <js...@ac...> - 2005-07-01 09:33:32
|
I have a piece of text
<suppcounts>
<pair> <count>18</count> <name>Ugly strchr error
in /lib/ld-2.3.3.so</name> </pair>
</suppcounts>
and I want to use sed to zap the entire contents between the <suppcounts>
tags, giving:
<suppcounts>...</suppcounts>
I tried this
sed "s/<suppcounts>.*<\/suppcounts>/<suppcounts>...<\/suppcounts>/"
but it doesn't work, I think because .* doesn't match newlines.
'man perlre' speaks of a 's' modifier which sounds like just the thing:
s Treat string as single line. That is, change "." to match any
character whatsoever, even a newline, which normally it would
not match.
It's not obvious [to me :-] how to use this, though. I tried patterns
like
<suppcounts>/s.*<\/suppcounts>
<suppcounts>\s.*<\/suppcounts>
but nothing works.
Anybody know a suitable magic incantation that will do it?
J
|
|
From: Tom H. <to...@co...> - 2005-07-01 09:45:29
|
In message <200...@ac...>
Julian Seward <js...@ac...> wrote:
> I tried this
>
> sed "s/<suppcounts>.*<\/suppcounts>/<suppcounts>...<\/suppcounts>/"
>
> but it doesn't work, I think because .* doesn't match newlines.
It's not that so much as the fact that sed is basically line
orientated, so the commands are applied to each line in turn. You
probably could write a more complicated sed script that appended
lines to the pattern space and then applied s to the whole pattern
space but it would be hard work and my sed isn't that good.
> 'man perlre' speaks of a 's' modifier which sounds like just the thing:
>
> s Treat string as single line. That is, change "." to match any
> character whatsoever, even a newline, which normally it would
> not match.
>
> It's not obvious [to me :-] how to use this, though. I tried patterns
> like
>
> <suppcounts>/s.*<\/suppcounts>
> <suppcounts>\s.*<\/suppcounts>
>
> but nothing works.
Modifiers on perl re's go after the final / of the replace operator
like this:
s/<suppcounts>.*<\/suppcounts>/<suppcounts>...<\/suppcounts>/s
You can put at least some of them inline with (?s:pattern) but as you
want to apply it to the whole pattern there is no point.
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|
|
From: <as...@qu...> - 2005-07-01 12:35:28
|
On Fri, 2005-07-01 at 12:28 +0100, Julian Seward wrote:
> > Modifiers on perl re's go after the final / of the replace operator
> > like this:
> >
> > s/<suppcounts>.*<\/suppcounts>/<suppcounts>...<\/suppcounts>/s
>=20
> Hmm, ok, so I need to use perl?
>=20
> So I changed memcheck/tests/filter_xml to be this
>=20
> #! /bin/sh
>=20
> ./filter_stderr |
> sed "s/<tid>[0-9]*<\/tid>/<tid>...<\/tid>/" |
> sed "s/<pid>[0-9]*<\/pid>/<pid>...<\/pid>/" |
> sed "s/<ppid>[0-9]*<\/ppid>/<ppid>...<\/ppid>/" |
> sed "s/<obj>.*<\/obj>/<obj>...<\/obj>/" |
> sed "s/<line>.*<\/line>/<line>...<\/line>/" |
> sed "s/<dir>.*<\/dir>/<dir>...<\/dir>/" |
> perl -e =
"s/<suppcounts>.*<\/suppcounts>/<suppcounts>...<\/suppcounts>/s"
>=20
> but now nothing at all comes out :-(
You can re-define the value of "newline" in perl via the variable "$/" a
couple of my scripts redefine this to \n\n although I believe you can
also set it to undef to allow multi-line matches.
>From the looks of it this would do it for you...
perl -e "$/=3Dundef; while (<>) { =
s/<suppcounts>.*<\/suppcounts>/<suppcounts>...<\/suppcounts>/s ;print =
$_}"
Ashley,
|
|
From: Nicholas N. <nj...@cs...> - 2005-07-01 12:58:16
|
On Fri, 1 Jul 2005, as...@qu... wrote:
>> From the looks of it this would do it for you...
>
> perl -e "$/=undef; while (<>) { s/<suppcounts>.*<\/suppcounts>/<suppcounts>...<\/suppcounts>/s ;print $_}"
That works for me when I pipe input in, ie:
cat foo | perl -e "..."
but not when I redirect from file:
perl -e "..." < foo
but it should be good enough for your purposes, Julian.
N
|
|
From: Julian S. <js...@ac...> - 2005-07-01 11:28:26
|
> Modifiers on perl re's go after the final / of the replace operator > like this: > > s/<suppcounts>.*<\/suppcounts>/<suppcounts>...<\/suppcounts>/s Hmm, ok, so I need to use perl? So I changed memcheck/tests/filter_xml to be this #! /bin/sh ./filter_stderr | sed "s/<tid>[0-9]*<\/tid>/<tid>...<\/tid>/" | sed "s/<pid>[0-9]*<\/pid>/<pid>...<\/pid>/" | sed "s/<ppid>[0-9]*<\/ppid>/<ppid>...<\/ppid>/" | sed "s/<obj>.*<\/obj>/<obj>...<\/obj>/" | sed "s/<line>.*<\/line>/<line>...<\/line>/" | sed "s/<dir>.*<\/dir>/<dir>...<\/dir>/" | perl -e "s/<suppcounts>.*<\/suppcounts>/<suppcounts>...<\/suppcounts>/s" but now nothing at all comes out :-( J |
|
From: Tom H. <to...@co...> - 2005-07-01 13:00:46
|
In message <200...@ac...>
Julian Seward <js...@ac...> wrote:
> So I changed memcheck/tests/filter_xml to be this
>
> #! /bin/sh
>
> ./filter_stderr |
> sed "s/<tid>[0-9]*<\/tid>/<tid>...<\/tid>/" |
> sed "s/<pid>[0-9]*<\/pid>/<pid>...<\/pid>/" |
> sed "s/<ppid>[0-9]*<\/ppid>/<ppid>...<\/ppid>/" |
> sed "s/<obj>.*<\/obj>/<obj>...<\/obj>/" |
> sed "s/<line>.*<\/line>/<line>...<\/line>/" |
> sed "s/<dir>.*<\/dir>/<dir>...<\/dir>/" |
> perl -e "s/<suppcounts>.*<\/suppcounts>/<suppcounts>...<\/suppcounts>/s"
>
> but now nothing at all comes out :-(
Two problems - one is that you need -p to force perl to loop over
the input lines and apply your expression to each one and then print
the results.
The other is that as somebody else said you need to change the input
record separator so that it reads in the whole file as a single line
which you can do with the -0 switch. So in total you want:
perl -0 -p -e "s/<suppcounts>.*<\/suppcounts>/<suppcounts>...<\/suppcounts>/s"
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|