How to find patterns across multiple lines using grep?

后端 未结 26 1710
你的背包
你的背包 2020-11-22 04:14

I want to find files that have \"abc\" AND \"efg\" in that order, and those two strings are on different lines in that file. Eg: a file with content:

blah bl         


        
相关标签:
26条回答
  • 2020-11-22 04:41

    I relied heavily on pcregrep, but with newer grep you do not need to install pcregrep for many of its features. Just use grep -P.

    In the example of the OP's question, I think the following options work nicely, with the second best matching how I understand the question:

    grep -Pzo "abc(.|\n)*efg" /tmp/tes*
    grep -Pzl "abc(.|\n)*efg" /tmp/tes*
    

    I copied the text as /tmp/test1 and deleted the 'g' and saved as /tmp/test2. Here is the output showing that the first shows the matched string and the second shows only the filename (typical -o is to show match and typical -l is to show only filename). Note that the 'z' is necessary for multiline and the '(.|\n)' means to match either 'anything other than newline' or 'newline' - i.e. anything:

    user@host:~$ grep -Pzo "abc(.|\n)*efg" /tmp/tes*
    /tmp/test1:abc blah
    blah blah..
    blah blah..
    blah blah..
    blah efg
    user@host:~$ grep -Pzl "abc(.|\n)*efg" /tmp/tes*
    /tmp/test1
    

    To determine if your version is new enough, run man grep and see if something similar to this appears near the top:

       -P, --perl-regexp
              Interpret  PATTERN  as a Perl regular expression (PCRE, see
              below).  This is highly experimental and grep -P may warn of
              unimplemented features.
    

    That is from GNU grep 2.10.

    0 讨论(0)
  • 2020-11-22 04:42

    To search recursively across all files (across multiple lines within each file) with BOTH strings present (i.e. string1 and string2 on different lines and both present in same file):

    grep -r -l 'string1' * > tmp; while read p; do grep -l 'string2' $p; done < tmp; rm tmp 
    

    To search recursively across all files (across multiple lines within each file) with EITHER string present (i.e. string1 and string2 on different lines and either present in same file):

    grep -r -l 'string1\|string2' * 
    
    0 讨论(0)
提交回复
热议问题