我正在尝试从本机PHP中的所有脚本中提取所有MySQL查询。我希望仅使用grep从下面的查询中提取表名。以下是我的努力浪费在我的想法上。
FROM 'tablename'
FROM tablename
FROM apn.tablename
FROM apn.table_name
FROM 'apn.tablename'
grep -ionER "(FROM)[[:space:]](.*[a-zA-Z\d_.\`])[\s]"
重要的是grep捕获在表名结束后立即停止捕获文本,而我的grep没有。
我需要结果来显示这些信息:
(脚本位置):(行号):(表名)
/var/www/sites... : Line 31 : example_table_name
答案 0 :(得分:2)
看起来后面会完成你想要的吗?
grep -P -i -o '(?<=from )\S+' *.php | sed -r 's/^\W|\W$//g'
如果您还想要打印文件名和行号,您可能需要for
循环:
for i in `grep -R --include=*.php -l -i 'FROM' /var/www/sites`; do grep -Pion '(?<=from )\S+' $i | sed -r -e "s/['\`\"]/ /g" -e 's#^#'$i'... : line #'; done
其工作原理如下:
grep
递归,打印文件名,不区分大小写搜索FROM
中的*.php
"from "
后面查找非空格,仅打印行号和匹配单词sed
将'"`
替换为空格,并在行的开头插入文件名rojo@pico:~$ cat Desktop/test.php
' SELECT * FROM `contacts` WHERE 1=1' test data here that should be cut out'
rojo@pico:~$ for i in `grep -R --include=*.php -l -i 'FROM' .`; do grep -Pion '(?<=from )\S+' $i | sed -r -e "s/['\`\"]/ /g" -e 's#^#'$i'... : line #'; done
./Desktop/test.php... : line 1: contacts
以下是使用awk
的另一种选择:
find /var/www/sites -type f -iname '*.php' -print0 | xargs -0 awk 'BEGIN {FS="from|FROM|where|WHERE"} {++x;} /from|FROM/ {printf "%s... : line %d : %s%s", FILENAME, x, $2, ORS}'
...但我还没弄明白如何让它围绕表名去掉引号/反引号/撇号。如果它很重要的话,我可能会通过sed
或tr
来管它,但是必须有更优雅的方式来实现它。
答案 1 :(得分:2)
不要使用grep。这是Awk的量身定制的工作:
awk '$1 == "FROM" { print $2 }'
编辑感谢@rojo提供此建议
awk 'BEGIN{FS="from|FROM|where|WHERE"} /from|FROM/ {print $2}'
编辑2 :使用文件名和行#
awk 'BEGIN{FS="from|FROM|where|WHERE"}
/from|FROM/ {printf ("%s:%d:%s\n", FILENAME, NR, $2)}'
答案 2 :(得分:0)
我尝试了以下这一行。它会以点,短划线和单引号为例,并拉出表名。您可以使用grep / gawk / sed部分并循环遍历PHP代码。
echo "select * from 'the_db.the_table' where the_result=1;" | grep -ioE "(from)[[:space:]]([a-zA-Z0-9\_\.\']*)[[:space:]]" | gawk '{ print $2 }' | sed -e s/\'//g the_db.the_table