2017-03-07 60 views
0

这个人花了我一晚的睡眠。防止awk将字符串从0开始转换为oct0

假设你有一个文件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是否有相同的行为,是否可以改变它?
  4. 开始带前导零
+0

'我对结果的解释是否正确?'是的,您的解释是正确的 –

+0

'(2)'只有我能想到'$ 1 == int(“04677”)'...... –

+0

' gawk有同样的行为吗?是的......'是否有可能改变它?'不知道 –

回答

3
  1. 数字是在awkoctal号码。 2495是八进制数4677的十进制值。

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

  3. 是的,它不会改变。


顺便说一句,的

awk '{if($1==4677){print $0;}}' file 

的ideomatic版本

awk '$1==4677' file 
3

我可以建议两个选择,你可以做一个字符串匹配引用你的关键寻找,所以“04677”将不匹配。

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

或者,如果你知道你的关键是数字,你可以添加零转换为十进制

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

谢谢。问题出现在脚本中运行awk,其中键04677是一个字符串,但该文件具有数字第一列(无前导零)。 “04677”选项将不起作用,因为该文件中的字符串不包含前导0.我认为如果我将其保留为数字,这并不重要,但八进制转换引起了我的警惕。我相信在这种情况下,04677 + 0选项可以很好地工作。 – gvrocha

+0

@gvrocha该评论意味着你的问题并不代表你真正的问题,所以我们一直在试图帮助你解决你没有的问题。请参阅http://stackoverflow.com/a/42653696/1745001。 –

2

当你写的$1==04677代替$1==4677告诉 awk来对待04677作为一个八进制数字,就像如果你写了$1==0x4677你会告诉awk把它当作十六进制,而用$1==4677""你会告诉awk把它当作一个字符串。如果你不想要这些,那就不要那样做。

UPDATE: WRT的评论你@karakfa's answer下进行:

的问题从脚本中运行AWK其中关键的04677 是一个字符串,但该文件有一个数字第一列出现(没有前导 零)。 “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),因此最终得到数字而非字符串比较。