有没有任何 AWK 语法检查器?

9

是否有任何AWK语法检查器?我对仅标记语法错误的最小检查器和类似lint的更广泛检查器都感兴趣。

它应该只是一个静态检查器,不依赖于运行脚本。

3个回答

10
如果你在Awk脚本的开头加上BEGIN { exit(0) } END { exit(0) },你可以确保你的所有代码都不会被运行。在BEGINEND期间退出可以防止其他的begin和exit块运行。如果Awk返回0,则表示你的脚本没有问题;否则就是语法错误。 如果你将代码片段放在单独的参数中,你将在错误消息中得到良好的行号。这个调用...
gawk --source 'BEGIN { exit(0) } END { exit(0) }' --file syntax-test.awk

提供以下错误消息:

gawk: syntax-test.awk:3:   x = f(
gawk: syntax-test.awk:3:         ^ unexpected newline or end of string

GNU Awk 的 --lint 可以发现全局变量和未定义的函数:

gawk: syntax-test.awk:5: warning: function `g': parameter `x' shadows global variable
gawk: warning: function `f' called but never defined

而GNU Awk的--posix选项可以发现一些兼容性问题:

gawk: syntax-test.awk:2: error: `delete array' is a gawk extension

更新: BEGINEND

虽然 END { exit(0) } 块看起来多余,但请比较以下三种用法之间的微妙差异:

$ echo | awk '
  BEGIN { print("at begin") }
  /.*/ { print("found match") }
  END { print("at end") }'
at begin
found match
at end

$ echo | awk '
  BEGIN { exit(0) }
  BEGIN { print("at begin") }
  /.*/ { print("found match") }
  END { print("at end") }'
at end

$ echo | awk '
  BEGIN { exit(0) } END { exit(0) }
  BEGIN { print("at begin") }
  /.*/ { print("found match") }
  END { print("at end") }'
在Awk中,在BEGIN块期间退出将取消所有其他BEGIN块,并且将防止匹配任何输入。在END期间退出是防止所有其他事件块运行的唯一方法;这就是为什么上面第三次调用显示没有执行任何打印语句。GNU Awk用户手册中有一节关于exit语句的内容。

“END { exit(0) }” 看起来似乎并不是必要的。或者我有什么遗漏吗? - Michael J. Barber
@Michael J. Barber:我已经更新了我的答案以展示其差异。 - Dan Cecile
@Michael J. Barber: :) 没问题。 - Dan Cecile

2

有关此文档的建议集中在awk和gawk之间的差异。它实际上是一个语法检查器还是兼容性检查?无论哪种方式,它都不太适合我的需求,因为它在运行时执行一些检查;我已编辑问题以明确说明。 - Michael J. Barber
哦,对于这个建议点赞,它肯定比我现在什么都没有要好。 - Michael J. Barber

0

如果需要一个最小的语法检查器,它会在第一个错误处停止,请尝试使用awk -f prog < /dev/null


2
但是这可能会在 awk 脚本中执行一些代码,尽管没有获取文件输入。例如 BEGIN { system("rm importantFile") } - Straff
1
确实,那看起来绝对不安全。 - Clément

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接