2011-08-20 54 views
0

以下程序打印出文件的名称,行数以及以超过五分之一行开始的情况下以//开头的行数。如何写在惯用的awk?

awk '$1 == "//" { a+=1 } END { if (a * 5 >= NR) {print FILENAME " " NR " " a}}' MyClass.java 

这工作,但嵌套{{}}让我怀疑,如果我这样做是正确的,知道的awk程序的典型结构为:

awk 'condition { actions }' 

所以我怀疑,像

awk '$1 == "//" { a+=1 } END && (a * 5 >= NR) {print FILENAME " " NR " " a}' MyClass.java 

会更合适,但每次这样的尝试给了语法错误。有没有正确的方法来做到这一点,或者我的方法是否合适。

+2

它的工作原理和它的可读性。你还能想要什么? – Ferruccio

+0

我想我可能想要的'更多'是它将以awk所期望的方式编写。也许是,我不知道。 –

+1

我不明白为什么嵌套块将是unidiomatic - 恰恰相反。如果内部块妨碍了你,只要该块包含单个语句,它就是可选的,但保留块分隔符实际上是一种很好的形式。 – tripleee

回答

2

还有其他方式可以表达它,但是您第一次用惯用语写下它。虽然作者倾向于尽可能地省略括号,但您仍然可以在整个AWK编程语言中找到类似的代码示例。他们应该知道。

好像阿霍,Weinberger和Kernighan的在语言其语法从C派生,当他们写的东西像这样

if (a * 5 >= NR) 
    print FILENAME " " NR " " a 

它完美地传达了块以下的if的发展经验,数百年声明应该包含一个且只有一个声明。

我有相当少的几个世纪的经验。每当我读取这样的东西,它就完美地传达了a)某人忘记输入{},以及b)其他人将通过向该块添加语句而不添加大括号来引入错误。

多年来,我一直训练自己,只要输入if即可输入。

if() {} 

然后我回去填写,如果需要的话可以断行。在我的普通编辑器中,“if”自动扩展为“if(){}”。我敢肯定,自从20世纪80年代中期以来,我一直没有忽略牙套。