Использование awk printf для urldecode текста - PullRequest
8 голосов
/ 16 сентября 2010

Я использую awk для кодирования некоторого текста.

Если я закодирую строку в оператор printf, например printf "%s", "\x3D", она правильно выдает =. То же самое, если у меня есть целая экранированная строка в качестве переменной.

Однако, если у меня есть только 3D, как я могу добавить \x, чтобы printf печатал =, а не \x3D?

Я использую busybox awk 1.4.2 и оболочку ash.

Ответы [ 5 ]

3 голосов
/ 16 сентября 2010

Я не знаю, как вы делаете это в awk, но в perl это тривиально:

echo "http://example.com/?q=foo%3Dbar" | 
    perl -pe 's/\+/ /g; s/%([0-9a-f]{2})/chr(hex($1))/eig'
2 голосов
/ 01 мая 2014

GNU awk

#!/usr/bin/awk -fn
@include "ord"
BEGIN {
  RS = "%.."
}
{
  printf RT ? $0 chr("0x" substr(RT, 2)) : $0
}

Или

#!/bin/sh
awk -niord '{printf RT?$0chr("0x"substr(RT,2)):$0}' RS=%..

Декодирование кодировки URL (в процентах)

1 голос
/ 16 сентября 2010

Поскольку вы используете Ash, а Perl недоступен, я предполагаю, что у вас может не быть gawk.

Для меня, используя gawk или busybox awk , ваш второй пример работает так же, как первый (я получаю "=" из обоих), если я не использую опцию --posix (в этом случае я получаю "x3D" для и ).

Если я использую --non-decimal-data или --traditional с gawk, я получаю "=".

Какую версию AWK вы используете (awk, nawk, gawk, busybox - и номер версии)?

Редактировать:

Вы можете принудитьстроковое значение переменной в числовое, добавив ноль:

~/busybox/awk 'BEGIN { string="3D"; pre="0x"; hex=pre string; printf "%c", hex+0}'
0 голосов
/ 19 октября 2017

Начнем с того, что я знаю, что это старый вопрос, но ни один из ответов не сработал для меня (только для busybox awk)

Два варианта. Для разбора стандартного ввода:

awk '{for (y=0;y<127;y++) if (y!=37) gsub(sprintf("%%%02x|%%%02X",y,y), y==38 ? "\\&" : sprintf("%c", y));gsub(/%25/, "%");print}'

Чтобы получить параметр командной строки:

awk 'BEGIN {for (y=0;y<127;y++) if (y!=37) gsub(sprintf("%%%02x|%%%02X",y,y), y==38 ? "\\&" : sprintf("%c", y), ARGV[1]);gsub(/%25/, "%", ARGV[1]);print ARGV[1]}' parameter

Последний должен выполнять% 25, ​​потому что в противном случае строки типа% 253D будут подвергнуты двойному анализу, что не должно происходить.

Встроенная проверка для y == 38 объясняется тем, что gsub обрабатывает & как специальный символ, если только вы не коснитесь его.

0 голосов
/ 23 февраля 2014

Это зависит от расширения функции разделения в gnu awk, но это работает:

gawk '{ numElems = split($0, arr, /%../, seps);
        outStr = ""
        for (i = 1; i <= numElems - 1; i++) {
            outStr = outStr arr[i]
            outStr = outStr sprintf("%c", strtonum("0x" substr(seps[i],2)))
        }
        outStr = outStr arr[i]
        print outStr
      }'
...