2010-09-16 9 views
8

Ich verwende awk, um Text urldecode.Verwenden von awk printf zu urldecode Text

Wenn ich die Zeichenfolge in die printf Anweisung wie printf "%s", "\x3D" kodiere, gibt sie korrekt = aus. Das gleiche, wenn ich die gesamte Escape-Zeichenfolge als Variable habe.

Allerdings, wenn ich nur die 3D haben, wie kann ich anfügen die \x so printf die = und nicht \x3D gedruckt werden?

Ich benutze busybox awk 1.4.2 und die ash Shell.

Antwort

1

Da Sie Asche sind und Perl nicht verfügbar ist, gehe ich davon aus, dass Sie möglicherweise nicht haben gawk.

Für mich mit gawk oder Busybox awk, Ihr zweites Beispiel funktioniert genauso wie das erste (I get "=" von beiden), es sei denn ich die --posix Option verwenden (in diesem Fall erhalte ich "X3D" für beide).

Wenn ich --non-decimal-data oder --traditional mit gawk verwende ich bekommen "=".

Welche Version von AWK verwenden Sie (awk, nawk, gawk, Busybox - und Versionsnummer)?

Edit:

Sie können den String-Wert in eine numerische eine der Variablen coerce Null durch Zugabe:

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

Sie haben recht, es funktioniert. Ich habe die falsche Frage gestellt - ich werde es ändern. (Ich benutze busybox awk, Version 1.4.2) – Johan

+0

@Johan: Siehe meine Bearbeitung. –

+0

Es dauerte eine Weile, bis mir klar wurde, dass dieser Einzeiler nur für __eine __ Variable, keine ganze urlencodierte Saite (z. B. eine Webadresse mit '% 20' und'% 3F' Zeug) – syntaxerror

3

Ich weiß nicht, wie Sie dies in awk tun, aber es ist trivial in Perl:

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

Danke, aber Perl ist nicht verfügbar. – Johan

+0

@zwol Dies funktioniert nur mit Perl 5, wenn Sie das '+' mit einem Backslash umgehen! Übrigens, funktioniert gut für mich mit Beispiel-URLs ohne die 's/\ +// g 'Teil überhaupt! Die zweite Regex allein wird schon den Trick machen. – syntaxerror

+0

@syntaxerror Du hast ganz recht damit, dass das '+' geflüchtet sein muss, ich weiß nicht, wie ich das verpasst habe. Ich denke, dass die "? Q = Phrase + getrennt + durch + plus + Zeichen" -Notation weniger üblich geworden ist, seit ich das geschrieben habe, aber es ist immer noch Teil der [Spezifikation für Anwendung/x-www-Form-urlencoded] (http: // www.w3.org/TR/html401/interact/forms.html#h-17.13.4) Entweichen von Formulareinreichungen. – zwol

0

Diese Gnu awk die Erweiterung der Split-Funktion beruht auf, aber dies funktioniert:

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

GNU awk

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

Oder

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

Decoding URL encoding (percent encoding)

+2

ist. UTF-8-codierte Nicht-ASCII-Zeichen –

0

mit zu beginnen, ich bin mir bewusst, dies eine alte Frage, aber keine der Antworten für mich (beschränkt auf busybox awk) arbeitete

Zwei Optionen. Zu analysieren stdin:

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

Um einen Kommandozeilenparameter übernehmen:

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 

tun% 25 zuletzt, weil sonst Strings wie% 253D bekommen doppelt analysiert, was nicht passieren sollte.

Die Inline-Prüfung für y == 38 ist, weil gsub behandelt & als ein Sonderzeichen, es sei denn Sie Backslash es.