bug-grep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug #25765] grep -P regexp also prints the line before the match


From: Wacek Kusnierczyk
Subject: Re: [bug #25765] grep -P regexp also prints the line before the match
Date: Thu, 05 Mar 2009 18:47:24 +0100
User-agent: Thunderbird 2.0.0.19 (X11/20090105)

Dave B wrote:
>
> Uhm, grep is supposed to not cross line boundaries, even with -P I'd say...
>   

yes, i'd think so, following man grep.

> Using Perl the result is different:
>
> $ printf 'a\n1\n' | perl -ne 'print if /^(|.*[^0])1/'
> 1
> $
>
> So I'd expect grep -P to produce the same result...which it doesn't.
>
> (and, besides that, there's the issue of an empty alternation being used,
> whose results might not always be specified, see eg POSIX)
>
>   
>> clearly, your test.s does not contain any single *line* that would match
>> the pattern -- but that's a problem with the documentation, i'd think,
>> which hasn't been updated to accommodate for the -P option which can
>> cause grep to match *across* lines, as above, and as here:
>>
>>     grep '.\n.' test.s
>>     # no match
>>     grep -P '.\n.' test.s
>>     # match
>>
>> i would certainly not consider this a bug, though.
>>     
>
> Perl does not match across lines by default, you have to use the /s flag in
> the match operator. Anyway, you might be correct, but then why doesn't grep
> -P show that behavior consistently?
>
> $ printf 'a\n1\n' | grep -P 'a.1'
> $
>
> $ printf 'a\n1\n' | grep -P 'a.*1'
> $
>
> If grep -P matched across lines, I'd expect the last two examples to output
>
> a
> 1
>
> and instead they don't output anything.
>   

the flag s makes perl match newlines with the dot;  grep -P seems to
work like perl regexes with the modifier m, which does not make dot
match newlines, but makes '^' and '$' match the start and end of each
line, rather than just the start and end of the whole string.  so the
two above are correct, that's what you'd see in perl:

    perl -le 'print "a\n1\n" =~ /^../g'
    # no match
    perl -le 'print "a\n1\n" =~ /^../sg'
    # one match
    perl -le 'print "a\n1\n" =~ /^../mg'
    # no match -- like your grep -P example above
    perl -le 'print "a\n1\n" =~ /^../msg'
    # two matches

but i'm still suspicious about grep working as perl in the m mode while
it "searches (...)  for *lines* containing  a  match to the given
PATTERN" (man grep).

vQ





reply via email to

[Prev in Thread] Current Thread [Next in Thread]