2010-09-16 14 views
8

Sto usando awk per urldecodificare del testo.Utilizzo di awk printf nel testo urldecode

Se codice la stringa nell'istruzione printf come printf "%s", "\x3D", emette correttamente =. Lo stesso se ho l'intera stringa di escape come variabile.

Tuttavia, se ho solo il 3D, come posso aggiungere il \x modo printf stamperà il = e non \x3D?

Sto usando busybox awk 1.4.2 e lo shell ash.

risposta

1

Dal momento che si sta utilizzando cenere e Perl non è disponibile, sto supponendo che non si può avere gawk.

Per me, utilizzando gawk o busybox awk, il tuo secondo esempio funziona lo stesso come il primo (ottengo "=" da entrambi) a meno che non si utilizza l'opzione --posix (nel qual caso ho "X3D" per entrambi).

Se uso --non-decimal-data o --traditional con gawk Ottengo "=".

Quale versione di AWK stai usando (awk, nawk, gawk, busybox - e numero di versione)?

Edit:

È possibile costringere valore stringa della variabile in uno numerica con l'aggiunta di zero:

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

Hai ragione, funziona. Ho fatto la domanda sbagliata - la correggerò. (Sto usando busybox awk, versione 1.4.2) – Johan

+0

@Johan: Vedi la mia modifica. –

+0

Mi ci è voluto un bel po 'per rendermi conto che questo one-liner è solo per una variabile __one__, nessuna stringa urlencoded completa (ad esempio un indirizzo web riempito con% 20 e roba% 3F) – syntaxerror

3

Io non so come si esegue questa operazione in awk, ma è banale in Perl:

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

Grazie, ma perl non è disponibile. – Johan

+0

@zwol Funziona solo su Perl 5 se si esegue il '+' con un backslash! BTW, per me funziona bene con URL di esempio senza la parte 's/\ +// g'! La seconda regex da sola farà già il trucco. – syntaxerror

+0

@syntaxerror Hai ragione sul fatto che '+' ha bisogno di essere scappato, non so come mi sia mancato. Penso che la notazione '? Q = phrase + separate + by + plus + sign' sia diventata meno comune da quando ho scritto questo, ma fa ancora parte della [spec per application/x-www-form-urlencoded] (http: // www.w3.org/TR/html401/interact/forms.html#h-17.13.4) escaping di invii di moduli. – zwol

0

Questo si basa su un'estensione di awk gnu della funzione split, ma questo funziona:

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 
} 

O

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

Decoding URL encoding (percent encoding)

+2

Questo non è disponibile ad es. Caratteri non ASCII codificati in UTF-8 –

0

Per cominciare, sono consapevole questa è una vecchia questione, ma nessuna delle risposte ha lavorato per me (limitato a busybox awk)

Two opzioni. Per analizzare 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}' 

Per avere un parametro di riga di 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 

dovete fare% 25 ultimo perché altrimenti stringhe come% 253D ottengono doppio analizzati, che non dovrebbe accadere.

Il controllo inline per y == 38 è perché gsub considera & come un carattere speciale a meno che non si esegua il backslash.