Wacek Kusnierczyk wrote: > Wacek Kusnierczyk wrote: >> Andriy Sen wrote: >> >>> See tree examples below. The last one shows the problem. >>> >>> >>> G:\>cat test.s >>> a >>> 1 >>> >>> G:\>od -a test.s >>> 0000000 a nl 1 nl >>> 0000004 >>> >>> G:\>cat test.s | grep -P "^[^0]1" >>> >>> >>> G:\>cat test.s | grep -P "^(|[^0])1" >>> 1 >>> >>> G:\>cat test.s | grep -P "^(|.*[^0])1" >>> a >>> 1 >>> >>> >>> >> what problem? >> >> cat test.s | grep -Pn "^(|.*[^0])1" >> # 1:a >> # 1 >> >> as you can see, there is one match here. '.*' matches 'a', and '[^0]' >> matches the newline. and so '1' can match '1'.
Uhm, grep is supposed to not cross line boundaries, even with -P I'd say... 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. -- D.
