【问题标题】:Prevent awk from converting string starting with 0 to oct防止 awk 将从 0 开始的字符串转换为 oct
【发布时间】:2017-03-08 00:58:01
【问题描述】:

这个让我睡了一晚。

假设你有一个文件 a_file.txt 如下。

1000    JUC_0000    1
2494    JUC_AAAA    2
2495    JUC_BBBB1   3
2495    JUC_BBBB2   4
4676    JUC_CCCC    5
4677    JUC_DDDD1   6
4677    JUC_DDDD2   7

如果你跑

awk '{if($1==4677){print $0;}}' a_file.txt

你会得到你所期望的:

4677    JUC_DDDD1   6
4677    JUC_DDDD2   7

但是,如果你运行

awk '{if($1==04677){print $0;}}' a_file.txt

你可能(我)很惊讶

2495    JUC_BBBB1   3
2495    JUC_BBBB2   4

似乎发生的事情是 awk 将 04677 解释为 2495 的八进制表示并使用它运行。

两个问题:

  1. 我对结果的解释是否正确?
  2. 有没有办法防止 awk 将以 0 开头的数字解释为八进制数,而改用十进制解释?
  3. gawk 是否具有相同的行为,是否可以更改?

【问题讨论】:

  • Is my interpretation of the result correct?是的,你的解释是正确的
  • (2) 只有我能想到$1==int("04677") ......
  • Does gawk have the same behaviour 是...is it possible to change it? 不知道
  • (2) $1=="04677"
  • 何塞:谢谢。 int 转换应该可以工作。

标签: awk gawk


【解决方案1】:
  1. 以零开头的数字是awk 中的octal 数字。 2495 是八进制数 4677 的十进制值。

  2. 没有以0 开头的十进制数 - 除了0 本身。

  3. 是的,不会改变。


顺便说一句,

的意识形态版本
awk '{if($1==4677){print $0;}}' file

awk '$1==4677' file

【讨论】:

    【解决方案2】:

    我可以建议两个替代方案,您可以通过引用您要查找的密钥来进行字符串匹配,因此“04677”将不匹配。

    $ awk '$1=="04677"' file
    

    或者,如果您知道您的密钥是数字,您可以添加零以转换为十进制

    $ awk '$1==04677+0' file
    

    【讨论】:

    • 谢谢。问题是在脚本中运行 awk 引起的,其中键 04677 是一个字符串,但文件有一个数字第一列(没有前导零)。 “04677”选项不起作用,因为文件上的字符串不包含前导 0。我原以为如果我将其保留为数字则无关紧要,但八进制转换让我措手不及。我相信 04677+0 选项在这种情况下会很好用。
    • @gvrocha 该评论意味着您的问题并不代表您的真正问题,因此我们一直在努力帮助您解决您没有的问题。见stackoverflow.com/a/42653696/1745001
    【解决方案3】:

    当你写 $1==04677 而不是 $1==4677 时,你是在告诉 awk 将 04677 当作八进制数,就像你写 $1==0x4677 时你会告诉 awk 来处理它作为十六进制并使用$1==4677"",您会告诉awk 将其视为字符串。如果你不想那样做,那就不要那样做。

    更新:写下您在@karakfa's answer 下发表的评论:

    问题源于在密钥为 04677 的脚本中运行 awk 是一个字符串,但文件有一个数字第一列(没有前导 零)。 “04677”选项不起作用,因为 文件不包含前导 0。我原以为这不会 不管我把它留下数字,但八进制转换让我失望 警卫。我相信 04677+0 选项在这种情况下会很好用。

    您刚才在该评论中描述的问题与您在问题中所说的完全不同。现在您不再将十进制与八进制进行比较,而是将数字与字符串进行比较,并且在这种情况下使用的操作是字符串比较(请参阅https://www.gnu.org/software/gawk/manual/gawk.html#Typing-and-Comparison)所以4677 != "04677" 因为第一个4677 的字符是"4"04677 的第一个字符是"0"。它与数字的八进制表示完全无关。是的,使用 "04677"+0 会起作用,因为这会将字符串转换为数字 (4677),因此您最终会得到一个数字而不是字符串的比较。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-21
      • 1970-01-01
      • 2014-10-18
      • 2013-11-18
      • 1970-01-01
      • 2021-09-14
      • 2013-02-03
      • 2023-02-09
      相关资源
      最近更新 更多