Regex (grep) for multi-line search needed
Without the need to install the grep variant pcregrep
, you can do a multiline search with grep.
$ grep -Pzo "(?s)^(\s*)\N*main.*?{.*?^\1}" *.c
Explanation:
-P
activate perl-regexp for grep (a powerful extension of regular expressions)
-z
Treat the input as a set of lines, each terminated by a zero byte (the ASCII NUL character) instead of a newline. That is, grep knows where the ends of the lines are, but sees the input as one big line. Beware this also adds a trailing NUL char if used with -o
, see comments.
-o
print only matching. Because we're using -z
, the whole file is like a single big line, so if there is a match, the entire file would be printed; this way it won't do that.
In regexp:
(?s)
activate PCRE_DOTALL
, which means that .
finds any character or newline
\N
find anything except newline, even with PCRE_DOTALL
activated
.*?
find .
in non-greedy mode, that is, stops as soon as possible.
^
find start of line
\1
backreference to the first group (\s*
). This is a try to find the same indentation of method.
As you can imagine, this search prints the main method in a C (*.c
) source file.
I am not very good in grep. But your problem can be solved using AWK command. Just see
awk '/select/,/from/' *.sql
The above code will result from first occurence of select
till first sequence of from
. Now you need to verify whether returned statements are having customername
or not. For this you can pipe the result. And can use awk or grep again.