awk - 括号检查

时间:2010-04-19 12:52:42

标签: linux awk brackets

我正在寻找awk中的脚本,它将检查它是否有适当的支架放置。使用过的括号是{} []和() 每个括号都应该关闭,括号不能混,非法例如:([)]

2 个答案:

答案 0 :(得分: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 /虽然它将删除它在最里面停止的所有平衡对错误条件并保留所有合适的括号。

第3点/可能是一个可利用的结果,虽然我不确定你想到的报告机制。

第2点/相对容易实现,但需要花费几分钟的时间来制作,所以我将由你来决定。

第1点/是非常棘手的因为你输入了一个全新的竞争领域,有时是嵌套的开头和结尾,或特殊字符的特殊引用规则......

答案 1 :(得分:1)

您必须逐个字符地阅读文件。建立一堆看到的开放式括号。当您看到一个关闭括号时,您可以从堆栈中弹出匹配的开括号,或者记录括号不匹配的错误。

awk不适合这份工作。我使用通用脚本语言(Perl / Tcl / etc)。