我正在寻找 awk 中的脚本,它将检查它是否有正确的括号放置。使用的括号是 {} [] 和 () 每个括号都应该闭合,括号不能混用,非法示例:( [ ) ]
2 回答
如果您尝试做的事情适用于通用语言,那么这是一个不平凡的问题。
首先,您将不得不担心注释和字符串。如果您想在使用正则表达式的编程语言上检查这一点,这将使您的任务再次变得更加困难。
所以在我进来就你的问题给你任何建议之前,我需要知道你的问题领域的局限性。如果您可以保证没有字符串、注释和正则表达式需要担心 - 或者更一般地说,在代码中除了您正在检查它们是否平衡的用途之外,括号可能没有其他地方使用 - 这将让生活变得简单很多。
了解您要检查的语言会很有帮助。
如果我假设没有噪音,即所有括号都是有用的括号,我的策略将是迭代的:
我会简单地查找并删除所有内部括号对:那些内部不包含括号的。这最好通过将所有行折叠成一条长行来完成(并找到一种机制来添加行引用,如果您需要获取该信息)。在这种情况下,搜索和替换非常简单:
它需要一个数组:
B["("]=")"; B["["]="]"; B["{"]="}"
并通过这些元素循环:
for (b in B) {gsub("[" b "][^][(){}]*[" B[b] "]", "", $0)}
我的测试文件如下:
#!/bin/awk
($1 == "PID") {
fo (i=1; i<NF; i++)
{
F[$i] = i
}
}
($1 + 0) > 0 {
count("VIRT")
count("RES")
count("SHR")
count("%MEM")
}
END {
pintf "VIRT=\t%12d\nRES=\t%12d\nSHR=\t%12d\n%%MEM=\t%5.1f%%\n", C["VIRT"], C["RES"], C["SHR"], C["%MEM"]
}
function count(c[)
{
f=F[c];
if ($f ~ /m$/)
{
$f = ($f+0) * 1024
}
C[c]+=($f+0)
}
我的完整脚本(没有行引用)如下:
cat test-file-for-brackets.txt | \
tr -d '\r\n' | \
awk \
'
BEGIN {
B["("]=")";
B["["]="]";
B["{"]="}"
}
{
m=1;
while(m>0)
{
m=0;
for (b in B)
{
m+=gsub("[" b "][^][(){}]*[" B[b] "]", "", $0)
}
};
print
}
'
该脚本的输出在括号的最里面非法使用处停止。但请注意:1/ 此脚本不适用于注释、正则表达式或字符串中的括号,2/ 它不会报告问题在原始文件中的位置,3/ 尽管它会删除所有平衡对,但它会停止在最里面错误条件并保留所有 englobbing 括号。
第 3 点/ 可能是一个可利用的结果,尽管我不确定您想到的报告机制。
第 2 点/ 相对容易实现,但需要花费几分钟以上的时间才能完成,所以我将由您自己解决。
第 1 点/ 是一个棘手的问题,因为您进入了一个全新的领域,有时是嵌套的开头和结尾,或者特殊字符的特殊引用规则……
您必须逐个字符地读取文件。构建一堆可见的开括号。当您看到一个右括号时,您可以将匹配的左括号从堆栈中弹出,或者记录一个括号不匹配的错误。
awk 不是这项工作的正确工具。我会使用通用脚本语言(Perl/Tcl/etc)。