我需要针对bash脚本运行一系列Python
源代码,该脚本包含检查全局变量是否存在的逻辑。我可以使用两个标准来查看变量是否为全局变量:
read file line by line
if there is an '=' (assignment sign) in the line AND no '#' in beginning of line (it is not commented out), check:
is there a 'def' string anywhere in the text above this assignment line, e.g. def function_name()?
if yes, variable within a function and hence not global
else, possible global variable
如何使用grep
,awk
或sed
实现此伪代码?我也对有关使用bash脚本查找全局变量的更好策略的建议持开放态度。
示例代码:
int a = 23
def func_name():
...body...
此代码未通过我们的测试。
示例代码2:
def function_name():
int a = 4
...
此代码通过了测试。
答案 0 :(得分:0)
我认为这不是一个好主意,但这是你的逻辑的文字实现:
awk -F= '
/^[^#]/ && NF > 1 && saw_def { print "not global:", $0; next }
NF > 1 { print "possibly global:", $0 }
{ saw_def = /def/ }
' file.py
这告诉awk使用=
作为四个pattern {action}
对的字段分隔符:
#
开头,有第二个字段(因此有一个=
),并设置saw_def
变量:=
:saw_def
设置为表示行上是否存在“def”的布尔值以下是一个未通过测试的示例:
def function_name():
int a = 4
int b = 8
您请求的逻辑会注意到a
不是全局的,b
可能是全局的。
这应该更好:
awk '
NF == 0 { next }
{
indent = match ($0, /[^ \t]/) - 1 # count of leading whitespace
has_assign = /^[^#]*=/
}
$1 == "def" && !in_def { in_def = indent; next }
indent > in_def && has_assign { print "not global:", $0; next }
indent <= in_def { in_def = 0 }
has_assign { print "possibly global:", $0 }
' file.py
这会尝试解析python代码,利用语言的强制缩进来跟踪函数定义的时间。五个pattern {action}
对是:
indent
设置为第一个前设置has_assign
之前的前导空格和制表符的数量,以确定是否存在变量赋值(a =
存在于任何#
)之前ind_def
跟踪当前缩进级别并停止此行的匹配next
):注意,我不确定awk
的所有版本都了解\t
,因此您可能需要一个文字标签。您可以在命令行中输入 Ctrl + v , Tab 。
我仍然认为自制的python解析器不是一个好主意。如果你真的在解析有效(和已知安全)的python代码,那么this similar question会得到实际加载代码的答案,这当然是确定的。如果您正在处理可能不安全的代码或类似python的代码,并且/或者您正在使用的系统上缺少python解释器,那么我的解决方案可能对快速代码审查很有用。