2017-03-07 51 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),因此最終得到數字而非字符串比較。

相關問題