如何使用awk,sed或grep检查源代码中的全局变量?

时间:2017-12-07 20:45:12

标签: bash shell awk sed grep

我需要针对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

如何使用grepawksed实现此伪代码?我也对有关使用bash脚本查找全局变量的更好策略的建议持开放态度。

示例代码:

int a = 23

def func_name():
    ...body...

此代码未通过我们的测试。

示例代码2:

def function_name():
    int a = 4
    ...

此代码通过了测试。

1 个答案:

答案 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}对的字段分隔符:

  1. 行以非#开头,有第二个字段(因此有一个=),并设置saw_def变量:
    打印行不是全球任务;转到下一行(停止模式匹配)
  2. 其他行有=
    打印该行可能是全局作业
  3. (任何与#1不匹配的行):
    saw_def设置为表示行上是否存在“def”的布尔值
  4. 以下是一个未通过测试的示例:

    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}对是:

    1. 无字段(空行):
      跳至下一行
    2. (匹配任何其他行):
      indent设置为第一个前设置has_assign之前的前导空格和制表符的数量,以确定是否存在变量赋值(a =存在于任何#)之前
    3. 第一个字段为“def”,我们尚未跟踪功能:
      使用ind_def跟踪当前缩进级别并停止此行的匹配
    4. 我们已经缩进到一个函数中,我们有一个任务:
      报告非全局变量赋值
    5. 缩进级别不超过最后一个函数:
      我们不再使用函数,将函数缩进级别设置为零
    6. 我们有一个变量赋值(并且还没有触发next):
      报告可能的全局变量赋值
    7. 注意,我不确定awk的所有版本都了解\t,因此您可能需要一个文字标签。您可以在命令行中输入 Ctrl + v Tab

      ⚠我仍然认为自制的python解析器不是一个好主意。如果你真的在解析有效(和已知安全)的python代码,那么this similar question会得到实际加载代码的答案,这当然是确定的。如果您正在处理可能不安全的代码或类似python的代码,并且/或者您正在使用的系统上缺少python解释器,那么我的解决方案可能对快速代码审查很有用。