这种将修改后的"$1"从"strnum"转换为"string"

  • 本文关键字:quot strnum 转换 string 修改 awk gnu
  • 更新时间 :
  • 英文 :

$ awk --version
GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)
Copyright (C) 1989, 1991-2019 Free Software Foundation.

我运行以下三个类似的命令,试图将$1和$2用作整数。在此期间,我在Awk中使用sub()来去除非数字标题字符@

然而,如果sub()特别对$1而不是对整个$0进行运算,则结果之后不会转换为整数。

然后,如果sub()$1中找不到匹配项,则转换也会进行:

$ echo @101 9 | awk '{sub(/^@/, "", $0); print "("$2" < "$1") is " ($2 < $1)}'
(9 < 101) is 1
$ echo @101 9 | awk '{sub(/^@/, "", $1); print "("$2" < "$1") is " ($2 < $1)}'
(9 < 101) is 0
$ echo  101 9 | awk '{sub(/^@/, "", $1); print "("$2" < "$1") is " ($2 < $1)}'
(9 < 101) is 1

因此,我不确定这是一个bug还是预期的行为。如果这是意料之中的事,我想找出背后的原因。

我预计第二种情况会产生与第一种或第三种情况相同的结果。


更新1:

我添加了类型转储:

$ cat dump-args.awk
function dump(text) {
printf text
printf ", $0 is "typeof($0)
printf ", $1 is "typeof($1)
printf ", $2 is "typeof($2)
print ""
}
$ echo @101 9 | awk '@include "dump-args.awk"; { dump("Initially"); sub(/^@/, "", $0); dump("After sub"); print "("$1" > "$2") is " ($1 > $2)}'
Initially, $0 is string, $1 is string, $2 is strnum
After sub, $0 is string, $1 is strnum, $2 is strnum
(101 > 9) is 1
$ echo @101 9 | awk '@include "dump-args.awk"; { dump("Initially"); sub(/^@/, "", $1); dump("After sub"); print "("$1" > "$2") is " ($1 > $2)}'
Initially, $0 is string, $1 is string, $2 is strnum
After sub, $0 is string, $1 is string, $2 is strnum
(101 > 9) is 0
$ echo  101 9 | awk '@include "dump-args.awk"; { dump("Initially"); sub(/^@/, "", $1); dump("After sub"); print "("$1" > "$2") is " ($1 > $2)}'
Initially, $0 is string, $1 is strnum, $2 is strnum
After sub, $0 is string, $1 is strnum, $2 is strnum
(101 > 9) is 1

由于一些评论和这些信息,现在更清楚$1的类型何时可能更改以及何时修复。但是


更新2:

大多数解释都没有强调我刚刚在减少测试用例时发现的以下差异:

$ echo @101 9 | awk '{ sub(/^@/, "", $1); print ($1 > $2)}'
0
$ echo  @91 9 | awk '{ sub(/^@/, "", $1); print ($1 > $2)}'
1

类型与@101:相同

$ echo  @91 9 | awk '@include "dump-args.awk"; { dump("Initially"); sub(/^@/, "", $1); dump("After sub"); print "("$1" > "$2") is " ($1 > $2)}'
Initially, $0 is string, $1 is string, $2 is strnum
After sub, $0 is string, $1 is string, $2 is strnum
(91 > 9) is 1

此行为是一个特性,例如

echo 20 101 9 | awk '{sub(/20/, "", $0); print $1}'

打印

101

因为awk在$0更改时重新编译记录,例如

echo 20 101 9 | awk '{sub(/20/, "", $1); print $1}'

不打印任何内容,因为$1是删除的,$1包含一个空字符串,这不会重新编译记录,在您的示例中,$1被转换为文本或整数

echo @101 9 | awk '{sub(/^@/, "", $1); print typeof($1)}'
echo @101 9 | awk '{sub(/^@/, "", $0); print typeof($1)}'
echo @101 9 | awk '{sub(/^@/, "", $1); $0=$0; print typeof($1)}'

在最后一行$0=$0重新编译记录,此打印,

字符串strnumstrnum