当awk接收到“0”作为输入,在某些情况下它的行为有所不同。代码如下:
var=$1
echo ""; echo -n 'o/p of $1=$1 ==>'; echo $var | awk '$1=$1'
echo "";echo -n 'o/p of {$1=$1;print} ==>';echo $var | awk '{$1=$1;print}'
echo "";echo -n 'o/p of $1==$1 ==>';echo $var | awk '$1==$1'
echo "";echo -n 'o/p of {$1==$1;print} ==>';echo $var | awk '{$1==$1;print}'
输出与“0”(数字零):
[root@host ~]# sh /tmp/te.sh 0
o/p of $1=$1 ==>
o/p of {$1=$1;print} ==>0
o/p of $1==$1 ==>0
o/p of {$1==$1;print} ==>0
[root@GORJALA ~]#
输出与“1”(第一):
[root@host ~]# sh /tmp/te.sh 1
o/p of $1=$1 ==>1
o/p of {$1=$1;print} ==>1
o/p of $1==$1 ==>1
o/p of {$1==$1;print} ==>1
[root@host ~]#
var=0; echo $var | awk '$1=$1'
为什么我使用and时会出现差异var=1; echo $var | awk '$1=$1'
?除了 之外,所有数字都工作正常0
。
版本:
- GNU bash,版本 4.2.46
- GNU Awk 4.0.2
- coreutils-8.22-24.el7.x86_64
答案1
来自GNU Awk 用户指南:
赋值是一个表达式,因此它有一个值——与被赋值的值相同。因此,“z = 1”是值为 1 的表达式。
所以
echo 0 | awk '$1=$1'
该模式的计算结果为 0 (FALSE)echo 1 | awk '$1=$1'
print
该模式的计算结果为 1 (TRUE),并且执行默认操作
答案2
我认为这不是数值的问题:标准转换可以解决这个问题(至少在这里)。
OP 显示了四种不同的 awk 代码,所有变体都为:pattern { action }
(一) 1 美元 = 1 美元
这会将 $1 重新分配给自己。它不是布尔测试,它是无操作(实际上),并且返回值 $1。如果 $1 是 0,则模式为错误的和默认值打印动作被完全跳过。如果 $1 非零,则输入被打印。
(b) { $1 = $1;打印; }
这会将 $1 重新分配给自己,这也是一个空操作。在没有模式的情况下,执行操作并输入总是打印。
(c) $1 == $1
这是一个布尔表达式永远正确。 0 是 0,1 是 1(土豚就是土豚)。在没有动作的情况下,输入是总是打印。
(d) { $1 == $1;打印; }
没有模式。比较结果为真布尔值,该布尔值被丢弃。输入是总是打印。
答案3
现有答案无法解释原因
echo 0 | awk '$0="0"'
echo 0 | awk '$0=substr($0,1)'
echo 0 | awk '$0=$0""'
将全部打印0
,但是
echo 0 | awk '$0'
echo 000 | awk '$0'
不会打印任何内容,但在所有情况下,模式表达式的计算结果都是0
。
为什么0
一种情况为真,另一种情况为假?
这是因为“字段变量”(运算符的结果$
)被视为特例,和(如果可能)会自动转换为数字字符串,如果在数值上等于0
,则在布尔上下文中使用时将被视为 false:
字符串值应被视为数字字符串如果它来自以下之一:
字段变量
getline()
来自函数的输入
FILENAME
ARGV
数组元素
ENVIRON
数组元素
split()
函数创建的数组元素命令行变量赋值
来自另一个数字字符串变量的变量赋值
[如果它看起来像一个数字,请阅读整个描述这里]
另请阅读RATIONALE
为什么需要数字字符串的概念和这种特殊情况,特别是关于诸如“ echo 0 000 | awk '$1==$2'
true,但不是”之类的比较echo 0 | awk '$1=="000"'
。
作为另一个怪癖,请注意,至少在某些实现中,$0
如果对子字段的赋值导致重新计算(当前输入记录),则它会丢失其神奇的“数字字符串”属性:
$ echo 0 | gawk '{$1=0} $0'
0
这似乎没有被标准涵盖,尽管它与标准 awk 所基于的 nawk/bwk 的行为相匹配(但不是 mawk 的行为)。
此外,允许 awk 实现将输入中的NAN
,INF
和识别INFINITY
为相应的浮点数,尽管对此的支持参差不齐且不一致。您可能仍然被咬伤,例如。
echo But his daughter named Nan | awk '$NF'
不在 FreeBSD 的 awk 中打印任何内容(bwk、original-awk)。
答案4
因为 $0 是整个记录(完整行),$1,$2,是领域(通常用空格分隔)在其中。