выпуск версии awk - конвертирование шестнадцатеричного числа в десятичное - PullRequest
2 голосов
/ 10 ноября 2011

Я обычно пишу скрипты на своем Mac, а затем, когда все готово, я запускаю их в свой тестовый ящик на работе.Проблема, с которой я здесь сталкиваюсь, заключается в том, что у меня есть поток данных, который представляет собой IP-адрес в шестнадцатеричном формате.Я использую смесь sed и awk для ее анализа и преобразования в более читаемый формат.

$echo $content12
cb5c860100000000000000000000000000 

[DoD@MBP-13~] 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 -

[DoD@MBP-13~] awk --version
awk version 20070501

[DoD@MBP-13~] 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 ]

3 голосов
/ 10 ноября 2011

Вы можете использовать --non-decimal-data параметр gawk, чтобы заставить его обрабатывать восьмеричные и шестнадцатеричные числа на входе:

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

против:

$ echo 0x10 | gawk '{ printf "%d", $1 }'
0
1 голос
/ 10 ноября 2011

По сути, эта проблема сводится к подаче printf строки параметров. printf - это оболочка, построенная так:

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 голосов
/ 10 ноября 2011

Очевидно, реализация 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), может подойти это решение.

...