2011-11-10 100 views
2

我通常在我的mac上編寫腳本,然後一旦準備就緒,我將它們sftp到我的測試框中。我在這裏面臨的問題是我有一個數據流,它是一個十六進制格式的I.P地址。我使用sed和awk混合來解析它並將其轉換爲更易讀的格式。awk版本問題 - 將十六進制轉換爲十進制

$echo $content12 
cb5c860100000000000000000000000000 

[[email protected]~] echo $content12 | 
sed -e 's/../&./g' -e 's/.$//' | sed 's/[0-9a-z][0-9a-z]/0x&/g' | 
awk -F"." '{for (i=1;i<NF;i++) printf ("%d\n", $i)}' | 
awk '{if (NR<5) printf $0; printf "."}' | sed 's/\.\.*$//' 
203.92.134.1 

當我將這個移植到我的測試框在工作時,腳本沒有按預期工作。

$echo $content12 | 
sed -e 's/../&./g' -e 's/.$//' | sed 's/[0-9a-z][0-9a-z]/0x&/g' | 
awk -F"." '{for (i=1;i<NF;i++) printf ("%d\n", $i)}' | 
awk '{if (NR<5) printf $0; printf "."}' | sed 's/\.\.*$//' 
0.0.0.0 

版本的awk和UNAME我的Mac上 -

[[email protected]~] awk --version 
awk version 20070501 

[[email protected]~] uname -a 
Darwin MBP-13.local 11.2.0 Darwin Kernel Version 11.2.0: Tue Aug 9 20:54:00 PDT 2011;  
root:xnu-1699.24.8~1/RELEASE_X86_64 x86_64 

版本的awk和UNAME在我的測試箱在工作 -

$ awk --version 
GNU Awk 3.1.5 
Copyright (C) 1989, 1991-2005 Free Software Foundation 

$uname -a 
Linux 2.6.18-194.el5 #1 SMP Tue Mar 16 21:52:39 EDT 2010 
x86_64 x86_64 x86_64 GNU/Linux 

這是不是我可以稍作修改。我對UNIX環境仍然很陌生,所以我對你的看法可能看起來異常漫長。任何建議將不勝感激。

回答

3

您可以使用gawk--non-decimal-data選項,使其在輸入處理八進制和十六進制數:

$ echo 0x10 | gawk --non-decimal-data '{ printf "%d", $1 }' 
16 

與:

$ echo 0x10 | gawk '{ printf "%d", $1 }' 
0 
+0

工程很棒。萬分感謝! –

0

顯然,GNU awk(1)執行不處理0x11作爲您實施它的printf()的參數:

$ echo cb5c860100000000000000000000000000 | sed -e 's/../&./g' -e 's/.$//' | 
    sed 's/[0-9a-z][0-9a-z]/0x&/g' 
0xcb.0x5c.0x86.0x01.0x00.0x00.0x00.0x00.0x00.0x00.0x00.0x00.0x00.0x00.0x00.0x00.0x00 
$ echo cb5c860100000000000000000000000000 | sed -e 's/../&./g' -e 's/.$//' | 
    sed 's/[0-9a-z][0-9a-z]/0x&/g' | 
    awk -F"." '{for (i=1;i<NF;i++) printf ("%d\n", $i)}' 
0 
0 
0 
... 

mawk(1)安裝在我的系統(由麥克·布倫南)上 - 以GNU awk(1)的替代品,聲稱自己是更小,更快,並且仍然POSIX 1003.2(草案11.3)兼容 - 將此解釋爲你的預期:

$ echo cb5c860100000000000000000000000000 | sed -e 's/../&./g' -e 's/.$//' | 
    sed 's/[0-9a-z][0-9a-z]/0x&/g' | 
    mawk -F"." '{for (i=1;i<NF;i++) printf ("%d\n", $i)}' | 
    mawk '{if (NR<5) printf $0; printf "."}' | sed 's/\.\.*$//' 
203.92.134.1$ 

如果你足夠幸運,也有mawk(1)安裝和使用,這種解決方案可能是合適的。

+0

謝謝sarnold。不幸的是,我沒有安裝在我的測試盒上。我將不得不使用系統管理員來部署它。我已經使用@Rick的答案,因爲它很容易實現。 –

+0

我也喜歡@裏克的回答,它比我的破壞性要小得多。當我看到他的回答時,我正在忙着閱讀'gawk(1)'手冊頁,試圖找出如何使用'CONVFMT',所以我放棄了。 :) – sarnold

1

實質上,這個問題歸結爲餵養printf一串參數。 printf是一個shell內建這樣:

echo "cb5c860100000000000000000000000000" | 
sed 's/\(.\{8\}\).*/\1/;s/../"0x&" /g;s/^/printf "%d.%d.%d.%d\n" /'|sh 
203.92.134.1 

在GNU sed中,您可以評估模式空間,就像這樣:

echo "cb5c860100000000000000000000000000" | 
sed 's/\(.\{8\}\).*/\1/;s/../"0x&" /g;s/^/printf "%d.%d.%d.%d" /e' 
203.92.134.1 

在編程中,我發現最難的不是編碼,但說什麼你意思是。

+0

感謝波通..這看起來很酷。 +1 –