为什么 awk 打印非空字符串和正数

为什么 awk 打印非空字符串和正数

我注意到一些使用而不是打印的awk示例(例如1print$0为了节省空间,我通常使用“1”。以及在这个网站上)。

这是一个记录在案的/安全的做法,还是在某些版本中可能会被破坏;过去、现在还是未来?

这里有些例子:

echo 'a-does-print-$0' | awk '"x"'    
echo 'b-does-print-$0' | awk '$0'   
echo 'c-does-print-$0' | awk '1'
echo 'd-does-print-$0' | awk '(1-2)'  
echo 'd-does-print-$0' | awk '{$0="abc"}1'  

echo 'nothing-prints' | awk '{$0="abc"}'  
echo 'nothing-prints' | awk '$999' 
echo 'nothing-prints' | awk '(1-1)'  
echo 'nothing-prints' | awk '1-1' 
echo 'nothing-prints' | awk '0' 
echo 'nothing-prints' | awk 'unsetVar' 
echo 'nothing-printw' | awk ''

echo 'crashes' | awk '-3.14159'
echo 'crashes' | awk '-2' 
echo 'crashes' | awk '-1'

答案1

所以...程序的格式awk是一系列EXPRESSION { ACTION }语句。如果您省略该ACTION部分, print则它假定为 ,如果您省略EXPRESSION,则它匹配所有内容。所以这会打印所有内容:

awk 1

因为您的表达式 ( 1) 的计算结果为“true”(并且您没有任何操作)。对于所有“x-does-print”示例都是如此,因为给定示例输入,它们都具有非零、非空EXPRESSION和 no ACTION。给定一个空输入行,$0在第二个示例中将不会输出任何内容。

同样,除第一个之外的“无打印”示例的表达式的计算结果为“假”(空字符串或数字 0)。该{$0="abc"}示例的工作方式有所不同:它不打印任何内容,因为它没有任何打印指令。给定一个至少包含 999 个字段的长输入行,第二个示例 ( $999) 实际上会打印出该行。

这是运作方式的基础awk。所以可以肯定的是,它已被记录下来,并且不会被破坏。

请注意,您的“崩溃”示例实际上并没有崩溃;而是崩溃了。您刚刚在 shell 语法中犯了一个基本错误。 awk 将以 开头的参数解释-为命令行选项。引用它们并不会改变任何事情。如果你想像这样传递 awk 负数,你需要在你的 awk 程序前面加上前缀,以--指示 awk 它应该停止处理选项:

echo 'crashes' | awk -- -3.14159

将打印“崩溃”,因为-3.14150既不是空字符串也不是数字 0。

答案2

GNUawk手册:

许多编程语言对“真”和“假”的概念有特殊的表示。此类语言通常使用特殊常量 true 和 false,或者可能使用它们的大写等效项。然而,awk 不同。它从 C 借用了一个非常简单的 true 和 false 概念。在 awk 中,任何非零数值或任何非空字符串值都是 true。任何其他值(零或空字符串“”)均为 false。

是的,这种用法是可移植的并且面向未来。

旁注,这显示了你的第二个例子,

echo 'b-does-print-$0' | awk '$0'  

不会打印每一个行,仅限 awk 解释为真正字符串的行,即空行或仅包含数字 0 的书写方式的行 ( 0, 00, 0.0e3, -.0, ...)。

相关内容