2010-09-16 12 views
8

Estoy usando awk para urldecode algo de texto.Usando awk printf para urldecode texto

Si codigo la cadena en la instrucción printf como printf "%s", "\x3D", emite correctamente =. Lo mismo si tengo toda la cadena escapada como una variable.

Sin embargo, si sólo tengo la 3D, ¿cómo puedo añadir el \x por lo printf imprimirá el = y no \x3D?

Estoy usando busybox awk 1.4.2 y el shell ash.

Respuesta

1

Dado que está utilizando la ceniza y Perl no está disponible, estoy suponiendo que no se puede tener gawk.

Para mí, usando gawk o busybox awk, su segundo ejemplo funciona igual que el primero (me sale "=" de ambos) a menos que utilice la opción --posix (en cuyo caso me sale "X3D" para ambos).

Si uso --non-decimal-data o --traditional con gawk obtengo "=".

¿Qué versión de AWK está utilizando (awk, nawk, gawk, busybox - y número de versión)?

Editar:

Puede coaccionar valor de cadena de la variable en uno numérico mediante la adición de cero:

~/busybox/awk 'BEGIN { string="3D"; pre="0x"; hex=pre string; printf "%c", hex+0}' 
+0

Tienes razón, funciona. Hice la pregunta incorrecta: la corregiré. (Estoy usando busybox awk, versión 1.4.2) – Johan

+0

@Johan: Ver mi edición. –

+0

Me tomó bastante tiempo darme cuenta de que este delineador es solo para __one__variable, no para todo el hechizo codificado (por ejemplo, una dirección web rellena con las materias '% 20' y '% 3F') – syntaxerror

3

No sé cómo se hace esto en awk, pero es trivial en Perl:

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

Gracias, pero perl no está disponible. – Johan

+0

@zwol ¡Esto solo funciona en Perl 5 si escapas el '+' con una barra invertida! Por cierto, funciona bien para mí con URL de muestra sin la parte 's/\ +// g' en absoluto! La segunda expresión regular ya hará el truco. – syntaxerror

+0

@syntaxerror Tiene toda la razón sobre el '+' que necesita escaparse, no sé cómo me lo perdí. Creo que la notación '? Q = phrase + separated + by + plus + signs' se ha vuelto menos común desde que escribí esto, pero todavía forma parte de [spec for application/x-www-form-urlencoded] (http: // www.w3.org/TR/html401/interact/forms.html#h-17.13.4) escape de envíos de formularios. – zwol

0

Esto se basa en la extensión de awk GNU de la función de división, pero esto funciona:

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 
     }' 
2

awk GNU

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

O

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

Decoding URL encoding (percent encoding)

+2

Esto ilegible, p. Caracteres no ASCII codificados en UTF-8 –

0

Para empezar, soy consciente de que esto es una vieja pregunta, pero ninguna de las respuestas trabajó para mí (restringido a awk busybox)

Dos opciones. Para analizar la entrada estándar:

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

a tomar un parámetro de línea de comando:

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 

tiene que hacer el 25% el pasado porque de lo contrario cadenas como% 253D obtienen doble analizado, que no debería suceder.

El cheque en línea para y == 38 es porque gsub trata & como un carácter especial a menos que lo barra hacia atrás.