Преобразование шестнадцатеричного в десятичное в bash без использования gawk - PullRequest
0 голосов
/ 11 октября 2018

Ввод:

cat test1.out
12 ,         maze|style=0x48570006, column area #=0x7, location=0x80000d
13 ,         maze|style=0x48570005, column area #=0x7, location=0x80aa0d
....
...
..
.

Требуется вывод:

12 ,         maze|style=0x48570006, column area #=0x7, location=8388621   <<<8388621 is decimal of 0x80000d
....

Я хочу преобразовать только последний столбец в десятичную.Я не могу использовать gawk, так как он не доступен на машинах нашей компании везде.Пробовал использовать awk --non-decimal-data, но это тоже не сработало.Интересно, может ли команда printf перевернуть последнее слово из шестнадцатеричного в десятичное.Любые другие идеи, которые вы можете предложить?

Ответы [ 5 ]

0 голосов
/ 11 октября 2018

Если у вас установлен Perl, то отсутствие Gawk довольно несущественно.

perl -pe 's/location=\K0x([0-9a-f]+)/ hex($1) /e' file
0 голосов
/ 11 октября 2018

Это может работать для вас (GNU sed и Bash):

sed 's/\(.*location=\)\(0x[0-9a-f]\+\)/echo "\1$((\2))"/Ie' file

Использовать сопоставление с образцом и обратные ссылки, чтобы разбить каждую строку, а затем оценить команду echo.

Альтернатива:

sed 's/\(.*location=\)\(0x[0-9a-f]\+\)/echo "\1$((\2))"/I' file | sh
0 голосов
/ 11 октября 2018

Подождите, вы не можете просто использовать printf в других ауках?Это не будет работать с gawk, но это работает с другими awk, верно?Например, с mawk:

$ mawk 'BEGIN{FS=OFS="="}{$NF=sprintf("%d", $NF);print}' file
12 ,         maze|style=0x48570006, column area #=0x7, location=8388621
13 ,         maze|style=0x48570005, column area #=0x7, location=8432141

Я тестировал с mawk, awk-20070501, awk-20121220 и Busybox awk.

Брошено после редактирования, но оставлено для комментариев:

Использование rev и cut для извлечения около последнего = и printf для преобразования в hex2dec:

$ while IFS='' read -r line || [[ -n "$line" ]] 
  do 
      printf "%s=%d\n" "$(echo "$line" | rev | cut -d = -f 2- | rev)" \
                        $(echo "$line" | rev | cut -d = -f 1 | rev) 
  done < file

Вывод:

12 ,         maze|style=0x48570006, column area #=0x7, location=8388621
13 ,         maze|style=0x48570005, column area #=0x7, location=8432141

0 голосов
/ 11 октября 2018

Учитывая, что функция strtonum () недоступна, как насчет:

#!/bin/bash

awk -F'location=0x' '

function hex2dec(str,
    i, x, c, tab) {
    for (i = 0; i <= 15; i++) {
            tab[substr("0123456789ABCDEF", i + 1, 1)] = i;
    }
    x = 0
    for (i = 1; i <= length(str); i++) {
            c = toupper(substr(str, i, 1))
            x = x * 16 + tab[c]
    }
    return x
}

{
    print $1 "location=" hex2dec($2)
}
' test1.out

, где hex2dec () - это домашняя замена strtonum ().

0 голосов
/ 11 октября 2018

Здесь нет необходимости в awk или любых других внешних командах: собственная математическая операция bash корректно обрабатывает шестнадцатеричные значения в арифметическом контексте (поэтому echo $((0xff)) испускает 255).

#!/usr/bin/env bash
#              ^^^^- must be really bash, not /bin/sh

location_re='location=(0x[[:xdigit:]]+)([[:space:]]|$)'

while read -r line; do
  if [[ $line =~ $location_re ]]; then
    hex=${BASH_REMATCH[1]}
    dec=$(( $hex ))
    printf '%s\n' "${line/location=$hex/location=$dec}"
  else
    printf '%s\n' "$line"
  fi
done

Вы можете увидеть это работает на https://ideone.com/uN7qNY

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...