英文:
awk || logical operator syntax when printing
问题
'NR==1 || ($11 > 0.01) && ($10 > 0.8) {print}'
"||" 表示“或”,为什么会打印所有内容?你能解释一下这段代码的逻辑吗?我理解第二部分对列 $11 和 $10 进行了数值条件的约束,但 "NR==1 ||" 是什么意思?
英文:
I saw the following:
'NR==1 || ($11 > 0.01) && ($10 > 0.8) {print}'
Are the || for "OR" why is everything printed though? Could you explain me the logic of this code snippet? I understand the second part where it imposes numerical conditions on column $11 and $10, but what does NR==1 || do?
答案1
得分: 2
在遇到代码中顺序不是由括号决定的情况下,就像在下面的代码中一样:
'NR==1 || ($11 > 0.01) && ($10 > 0.8) {print}'
优先级 规则被使用,&&
的优先级高于 ||
,换句话说,&&
比 ||
更"粘性",因此上述代码等价于:
'NR==1 || (($11 > 0.01) && ($10 > 0.8)) {print}'
与之相比,如果&&
和 ||
具有相同的优先级,代码将如下所示:
'(NR==1 || ($11 > 0.01)) && ($10 > 0.8) {print}'
中缀表示法是模棱两可的,使用它的语言设计者必须制定有关优先级的规则,这可能因语言而异。即使不是严格必要的,使用圆括号将使您的代码更容易理解,因为读者可能不熟悉该特定语言的优先级规则。在GNU AWK的情况下:
> 运算符的正常优先级可以通过使用括号来覆盖。可以将优先级规则看作是括号被假定放置的位置。事实上,在存在不寻常的运算符组合时,明智的做法是始终使用括号,因为阅读程序的其他人可能不记得在这种情况下的优先级是什么。即使经验丰富的程序员偶尔也会忘记确切的规则,这可能导致错误。显式的括号有助于防止任何此类错误。
摘自GNU Awk用户指南
英文:
When encountering code where order is not determined by brackets like in
'NR==1 || ($11 > 0.01) && ($10 > 0.8) {print}'
Precedence rules are used, &&
is above ||
or in other words &&
is more sticky than ||
therefore above is equivalent to
'NR==1 || (($11 > 0.01) && ($10 > 0.8)) {print}'
compare that with
'(NR==1 || ($11 > 0.01)) && ($10 > 0.8) {print}'
which would be case if &&
and ||
would share same level of precedence.
Infix notation is ambigue, language designers who use it must made rules regarding precedence, which might differ between languages. Using round brackets, even if not strictly necessary, will make your code easier to digest for reader who does not know precedence rules by heart for that particular language. In case of GNU AWK
> The normal precedence of the operators can be overruled by using
> parentheses. Think of the precedence rules as saying where the
> parentheses are assumed to be. In fact, it is wise to always use
> parentheses whenever there is an unusual combination of operators,
> because other people who read the program may not remember what the
> precedence is in this case. Even experienced programmers occasionally
> forget the exact rules, which leads to mistakes. Explicit parentheses
> help prevent any such mistakes.
from The GNU Awk User' Guide
答案2
得分: 1
这种结构被称为短路评估。
它在Shell编程或类似C的语言中被广泛使用,其中第一项的真实性将影响语句其余部分的评估。
以下是awk中的一个示例。
首先,这将打印2的倍数:
seq 10 | awk '$1%2==0'
2
4
6
8
10
现在假设你想将3
添加到输出序列中:
seq 10 | awk '$1==3 || $1%2==0'
2
3
4
6
8
10
短路评估在Bash
中广泛使用,因为条件语句有点冗长。
这个:
if [[ -e "$filename" ]]; then
echo "exists"
else
echo "file does not exist"
fi
可以替换为:
[[ -e "$filename" ]] && echo "file exists" || echo "file does not exist"
虽然在功能上是等效的,但并不完全等同,因为&&
后面的第二个子句可能返回逻辑否定,然后||
后面的子句可能错误执行。在if ... then
中不会发生这种情况。
英文:
This structure is call Short-circuit evaluation.
It is used extensively in shell programming or C type languages where the truthiness of the first item will effect the evaluation of the remainder of the statement.
Here is an example in awk.
First, this prints multiples of 2:
seq 10 | awk '$1%2==0'
2
4
6
8
10
Now suppose you want to add 3
as being part of the output sequence:
seq 10 | awk '$1==3 || $1%2==0'
2
3
4
6
8
10
Short-circuit evaluation is exensively used in Bash
since the conditionals are kinda wordy.
This:
if [[ -e "$filename" ]]; then
echo "exists"
else
echo "file does not exist"
fi
Can be replaced with:
[[ -e "$filename" ]] && echo "file exists" || echo "file does not exist"
While that is functionally equivalent but not exactly equivelent since this is not a replacement for if ... then
. The second clause after the &&
could return a logical negative and then clause after the ||
would execute perhaps falsely. In the if ... then
that does not happen.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论