0

I need to identify all queries in a php source code spread in many files under different directories.

I though about using grep and MySQL keywords to identify them. There are two ways I can differentiate queries in this source code.

  1. They are always quoted in double quotes.
  2. They will always have the MySQL keywords such as insert, select, update, delete and alter.

But there is a problem, the queries in double quotes can be spread in multiple lines. Example :

$newQuery = "Select username
             from 
             usertable"

So I need to identify "Select username from usertable"

But grep can not work on multiple lines.

I tried :

egrep -e '"(.*?)\+"' test.php | grep "select"

It works great for single line but again misses multiline queries.

So I tried

sed -e '/\"/,/\"/!d' test.php

It returns all the queries, But then I do

sed -e '/\"/,/\"/!d' test.php | grep select

It returns,

"select 

which is not good. I think I need to escape newlines in sed. How do I achieve this? Any other standard commands for bash will also do, such as awk.

Jakub M.
  • 32,471
  • 48
  • 110
  • 179
user1263746
  • 5,788
  • 4
  • 24
  • 28

2 Answers2

1

I often use perl -pe instead of sed for some more fancy expressions.

cat tmp.php | \
perl -pe "s/[\n\r\s]+/ /g" | \ # remove all spaces and line breaks
perl -e '$x=join " ", (<>); print join " ", ($x =~ /".*?(?:select|alter).*?"/gi)'

In the last line you find all the quotes with select keyword and join them

Community
  • 1
  • 1
Jakub M.
  • 32,471
  • 48
  • 110
  • 179
  • Great! I skipped the last select part, redirected all the output in a file and then grepped the file with all the keywords. Its perfect, but I need to do this individually on all the files. – user1263746 Apr 02 '13 at 06:54
1

One way using Perl:

perl -00ne 'print $1,"\n" while (/"((select|insert|update|delete|alter).*?)"/sig);' file

To get output in single line:

perl -00ne 'while (/"((select|insert|update|delete|alter).*?)"/sig){$x=$1;$x=~s/\n//g;$x=~s/\s+/ /g;print "$x\n";};' file

To get single line output using join and split:

perl -00ne 'print join " ",split(/\s+/,$1),"\n" while (/"((select|insert|update|delete|alter).*?)"/sig);' file
Guru
  • 16,456
  • 2
  • 33
  • 46
  • It does work for the sample snippet you have put. "Not working" means no output, or output not as expected? – Guru Apr 02 '13 at 06:59
  • If you read the question carefully, you will find that sed solution I tried provides exactly the same output your solutions produces. But I need the result in single line rather then multiline. Else your solution is neat and easy to understand. The output should be like : "Select username from usertable" in a single line. Thanks! – user1263746 Apr 02 '13 at 07:06