Decodifica codifica URL (codifica percentuale)


100

Voglio decodificare la codifica URL, esiste uno strumento integrato per farlo o qualcuno potrebbe fornirmi un sedcodice che lo farà?

Ho cercato un po 'attraverso unix.stackexchange.com e su Internet ma non sono riuscito a trovare alcun strumento da riga di comando per decodificare la codifica dell'URL.

Quello che voglio fare è semplicemente sul posto modificare un txtfile in modo che:

  • %21 diventa !
  • %23 diventa #
  • %24 diventa $
  • %26 diventa &
  • %27 diventa '
  • %28 diventa (
  • %29 diventa )

E così via.


Risposte:


107

Ho trovato queste fodere Python one che fanno quello che vuoi:

$ alias urldecode='python -c "import sys, urllib as ul; \
    print ul.unquote_plus(sys.argv[1])"'

$ alias urlencode='python -c "import sys, urllib as ul; \
    print ul.quote_plus(sys.argv[1])"'

Esempio

$ urldecode 'q+werty%3D%2F%3B'
q werty=/;

$ urlencode 'q werty=/;'
q+werty%3D%2F%3B

Riferimenti


Lo so molto tardi, ma c'è un modo per farlo con la modifica sul posto?
DisplayName

@DisplayName: suona come una nuova Q per me. Lo chiederei e fare riferimento a questo.
slm

15
streaming:cat your_lovely_file.csv| python -c "import sys, urllib as ul; [sys.stdout.write(ul.quote_plus(l)) for l in sys.stdin]"
kirill_igum

5
Si noti che questo è un Python 2; sui sistemi in cui pythonè 3 per impostazione predefinita, ciò comporterà un errore. Cambiare pythonin python2aiuta.
Ivan Kolmychek,

4
Per python3te puoi usare import urllib.parse as ulinvece di import urllib as ul.
ibotty,

61

sed

Prova la seguente riga di comando:

$ sed 's@+@ @g;s@%@\\x@g' file | xargs -0 printf "%b"

o la seguente alternativa usando echo -e:

$ sed -e's/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g' file | xargs echo -e

Nota: la sintassi di cui sopra potrebbe non essere convertita +in spazi e può utilizzare tutte le nuove righe.


È possibile definirlo come alias e aggiungerlo ai file rc della shell :

$ alias urldecode='sed "s@+@ @g;s@%@\\\\x@g" | xargs -0 printf "%b"'

Quindi ogni volta che ne hai bisogno, vai semplicemente con:

$ echo "http%3A%2F%2Fwww" | urldecode
http://www

bash

Durante lo scripting, è possibile utilizzare la sintassi seguente:

input="http%3A%2F%2Fwww"
decoded=$(printf '%b' "${input//%/\\x}")

Comunque la sintassi sopra non gestirà +correttamente i plus ( ), quindi devi sostituirli con spazi tramite sed.

È inoltre possibile utilizzare le seguenti funzioni urlencode()e urldecode()funzioni:

urlencode() {
    # urlencode <string>
    local length="${#1}"
    for (( i = 0; i < length; i++ )); do
        local c="${1:i:1}"
        case $c in
            [a-zA-Z0-9.~_-]) printf "$c" ;;
            *) printf '%%%02X' "'$c" ;;
        esac
    done
}

urldecode() {
    # urldecode <string>

    local url_encoded="${1//+/ }"
    printf '%b' "${url_encoded//%/\\x}"
}

Si noti che sopra urldecode()presuppone che i dati non contengano barre rovesciate.

Ecco una versione simile di Joel disponibile su: https://github.com/sixarm/urldecode.sh


bash + xxd

Funzione Bash con xxdstrumento:

urlencode() {
  local length="${#1}"
  for (( i = 0; i < length; i++ )); do
    local c="${1:i:1}"
    case $c in
      [a-zA-Z0-9.~_-]) printf "$c" ;;
    *) printf "$c" | xxd -p -c1 | while read x;do printf "%%%s" "$x";done
  esac
done
}

Si trova nel file gist di cdown , anche su StackOverflow .


PHP

Utilizzando PHP puoi provare il seguente comando:

$ echo oil+and+gas | php -r 'echo urldecode(fgets(STDIN));' // Or: php://stdin
oil and gas

o semplicemente:

php -r 'echo urldecode("oil+and+gas");'

Utilizzare -Rper input su più righe.


Perl

In Perl puoi usare URI::Escape.

decoded_url=$(perl -MURI::Escape -e 'print uri_unescape($ARGV[0])' "$encoded_url")

O per elaborare un file:

perl -i -MURI::Escape -e 'print uri_unescape($ARGV[0])' file

awk

Prova una soluzione anon :

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

Nota: il parametro -nè specifico di GNU awk.

Vedere: Utilizzo di awk printf per codificare il testo .

decodifica dei nomi dei file

Se è necessario rimuovere la codifica URL dai nomi dei file, utilizzare lo deurlnamestrumento da renameutils(ad es deurlname *.*.).

Guarda anche:


Relazionato:


1
awk: Poiché utilizza una funzione di libreria chr(), esiste un'alta probabilità che funzioni solo su GNU awk ( gawk). Tuttavia, in questo caso non ci sarà quasi nessun equivalente per POSIX awk, perché l' -nopzione (che consente argomenti non decimali) È una awkspecialità GNU .
syntaxerror,

Il tuo primo sedcodice mi dà xargs: argument line too longun file con ≥2164 righe.
Sparhawk,

2
Le tue soluzioni che coinvolgono printfnon tengono conto del fatto che l'URL potrebbe contenere segni di percentuale sfuggiti come %25. Li passi a printf senza sfuggirli per printf con un altro segno di percentuale come %%.
josch,

1
La versione bash richiede local LC_ALL=Cin alto, altrimenti tutti i caratteri di grandi dimensioni (ad esempio giapponese, cinese, ecc.) Non sono suddivisi correttamente in byte.
Phernost,


18

C'è una funzione integrata per quello nella libreria standard di Python. In Python 2, lo è urllib.unquote.

decoded_url=$(python2 -c 'import sys, urllib; print urllib.unquote(sys.argv[1])' "$encoded_url")

O per elaborare un file:

python2 -c 'import sys, urllib; print urllib.unquote(sys.stdin.read())' <file >file.new &&
mv -f file.new file

In Python 3, lo è urllib.parse.unquote.

decoded_url=$(python3 -c 'import sys, urllib.parse; print(urllib.parse.unquote(sys.argv[1]))' "$encoded_url")

O per elaborare un file:

python3 -c 'import sys, urllib; print(urllib.parse.unquote(sys.stdin.read()))' <file >file.new &&
mv -f file.new file

In Perl puoi usare URI::Escape.

decoded_url=$(perl -MURI::Escape -e 'print uri_unescape($ARGV[0])' "$encoded_url")

O per elaborare un file:

perl -i -MURI::Escape -e 'print uri_unescape($ARGV[0])' file

Se si desidera attenersi agli strumenti portatili POSIX, è imbarazzante, perché l'unico candidato serio è awk, che non analizza i numeri esadecimali. Vedere Uso di awk printf per codificare il testo del codice per esempi con implementazioni awk comuni, incluso BusyBox.


10

Se si desidera utilizzare un sedcomando semplice , utilizzare quanto segue:

sed -e 's/%21/!/g' -e 's/%23/#/g' -e 's/%24/$/g' -e 's/%26/\&/g' -e "s/%27/'/g" -e 's/%28/(/g' -e 's/%29/)/g'

Ma è più conveniente creare uno script come (diciamo sedscript):

s/%21/!/g
s/%23/#/g
s/%24/$/g
s/%26/\&/g
s/%27/'/g
s/%28/(/g
s/%29/)/g

Quindi eseguire sed -f sedscript < old > new, che verrà emesso come desiderato.


Per semplicità, il comando urlencodeè anche disponibile direttamente nel gridsite-clientspacchetto che può essere installato da ( sudo apt-get install gridsite-clientsnel sistema Ubuntu / Debian).

NOME

    urlencode - converte le stringhe in o da un modulo con codifica URL
SINOSSI

    urlencode [-m|-d] string [string ...]

DESCRIZIONE

    urlencode codifica le stringhe secondo RFC 1738.

    Cioè, i caratteri A- Z a- z 0- 9 . _e -vengono passati non modificati, ma tutti gli altri caratteri sono rappresentati come% HH, dove HH è la loro rappresentazione ASCII esadecimale a due cifre maiuscole. Ad esempio, l'URL http://www.gridpp.ac.uk/diventahttp%3A%2F%2Fwww.gridpp.ac.uk%2F

    urlencodeconverte ogni carattere in tutte le stringhe fornite nella riga di comando. Se vengono fornite più stringhe, vengono concatenate con spazi di separazione prima della conversione.

OPZIONI
    -m
      Invece della conversione completa, esegui la "codifica URL lieve" di GridSite in cui AZ az 0-9. = - _ @ e / vengono passati non modificati. Ciò si traduce in stringhe leggermente più leggibili dall'uomo, ma l'applicazione deve essere preparata per creare o simulare le directory implicite da eventuali barre.
    -d
      Esegui la decodifica URL anziché la codifica, secondo RFC 1738. Le stringhe% HH e% hh vengono convertite e gli altri caratteri passano attraverso non modificati, con l'eccezione che +viene convertita nello spazio.

Esempio di URL di decodifica:

$ urlencode -d "http%3a%2f%2funix.stackexchange.com%2f"
http://unix.stackexchange.com/

$ urlencode -d "Example: %21, %22, . . . , %29 etc"
Example: !, ", . . . , ) etc

Per tutorial in sed visita
Pandya,

4
Questa è una pessima soluzione, perché richiede l'hardcoding di ogni personaggio. Questo problema è esemplificato dal codice mancante della %20sequenza di escape spesso utilizzata .
Overv

@Overv Ho appena rivisto
Pandya,

Inoltre, potresti voler ricontrollare cosa s/%26/&/gfa. (L'ho risolto.)
G-Man il

9

Perl one liner:

$ perl -pe 's/\%(\w\w)/chr hex $1/ge'

Esempio:

$ echo '%21%22' |  perl -pe 's/\%(\w\w)/chr hex $1/ge'
!"

1
Questa risposta è interessante quando non vuoi occuparti dell'installazione dei moduli perl.
Sridhar Sarnobat,

1
Solo uno che ha funzionato elegantemente per me su MacOS.
Qix,


7

Non posso commentare la migliore risposta in questa discussione , quindi ecco la mia.

Personalmente, utilizzo questi alias per la codifica e decodifica URL:

alias urlencode='python -c "import urllib, sys; print urllib.quote(  sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1])"'

alias urldecode='python -c "import urllib, sys; print urllib.unquote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1])"'

Entrambi i comandi consentono di convertire i dati, passati come argomento della riga di comando o di leggerli dall'input standard , poiché entrambi i caratteri di una riga controllano se esistono argomenti della riga di comando (anche vuoti) e li elaborano o semplicemente leggono l'input standard in altro modo.


aggiornamento 23/05/2017 (codifica barra)

In risposta al commento di @ Bevor.

Se è necessario codificare anche la barra, è sufficiente aggiungere un secondo argomento vuoto alla funzione quote, quindi verrà anche codificata la barra.

Quindi, finalmente l' urlencode alias in bash è simile al seguente:

alias urlencode='python -c "import urllib, sys; print urllib.quote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1], \"\")"'

Esempio

$ urlencode "Проба пера/Pen test"
%D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test

$ echo "Проба пера/Pen test" | urlencode
%D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test

$ urldecode %D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test
Проба пера/Pen test

$ echo "%D0%9F%D1%80%D0%BE%D0%B1%D0%B0%20%D0%BF%D0%B5%D1%80%D0%B0%2FPen%20test" | urldecode
Проба пера/Pen test

$ urlencode "Проба пера/Pen test" | urldecode
Проба пера/Pen test

$ echo "Проба пера/Pen test" | urlencode | urldecode
Проба пера/Pen test

1
Non codifica le barre.
Bevor

@Bevor: Esempio?
DIG mbl

Aggiungi una barra all'urlencode "Проба пера" -> risultato: la barra non è codificata.
Bevor

1
@Bevor: hai ragione. Grazie per il tuo commento. Cambierò anche la mia risposta per riflettere il tuo commento in esso.
DIG mbl,

4

E un altro approccio Perl:

#!/usr/bin/env perl
use URI::Encode;
my $uri     = URI::Encode->new( { encode_reserved => 0 } );
while (<>) {

    print $uri->decode($_)
}

Dovrai installare il URI::Encodemodulo. Sul mio Debian, potrei semplicemente correre

sudo apt-get install liburi-encode-perl

Quindi, ho eseguito lo script sopra su un file di prova contenente:

http://foo%21asd%23asd%24%26asd%27asd%28asd%29

Il risultato è stato (avevo salvato lo script come foo.pl):

$ ./foo.pl
http://foo!asd#asd$&asd'asd(asd)

3

Una risposta nella shell (principalmente Posix):

$ input='%21%22'
$ printf "`printf "%s\n" "$input" | sed -e 's/+/ /g' -e 's/%\(..\)/\\\\x\1/g'`"
!"

Spiegazione:

  • -e 's/+/ /gtrasforma ciascuno +nello spazio (come descritto nella norma codifica url)
  • -e 's/%\(..\)/\\\\x\1/g'trasformare ciascuno %XXin \\xXX. Si noti che uno dei \sarà rimosso citando le regole.
  • Il printf interno è lì solo per passare l'input a sed. Possiamo sostituirlo con qualsiasi altro meccanismo
  • La stampa esterna interpreta le \\xXXsequenze e visualizza il risultato.

Modificare:

Poiché %dovrebbe sempre essere interpretato negli URL, è possibile semplificare questa risposta. Inoltre, penso che sia più pulito da usare al xargsposto dei backquotes (grazie a @josch).

$ input='%21%22+%25'
$ printf "%s\n" "$input" | sed -e 's/+/ /g; s/%/\\x/g' | xargs -0 printf
!" %

Sfortunatamente, (come notato da @josch) nessuna di queste soluzioni è conforme a Posix poiché la \xsequenza di escape non è definita in Posix.


Benvenuto in U&L. Forse potresti spiegare questa risposta e come funziona. In genere preferiamo che le nostre risposte siano lunghe con dettagli, non solo frammenti di codice.
slm

Mi piace molto questa risposta perché è completa, portatile e non richiede programmi esterni più pesanti come perl o python. Funziona bene per me.
Steve Wills,

1
Ottima soluzione E ancora più breve e più intelligente: ... | sed 's/+/ /g;s/%\(..\)/\\\\x\1/g'. L' -eopzione può essere omessa qui in effetti ...
syntaxerror,

1
@josch Hai ragione, printfè integrato dashe non riconosce la \xfuga. Puoi usarlo /usr/bin/printfinvece di printffarlo funzionare. Normalmente, dovresti essere in grado di utilizzare command printf, ma sembra non funzionare come dovrebbe. Continua a utilizzare il built-in.
Jérôme Pouiller,

1
@Jezz infatti il ​​supporto per la \xfuga non fa parte di POSIX: pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html Durante i miei test ho riscontrato un altro problema. Potresti voler sostituire la tua ..regex [a-zA-Z0-9][a-zA-Z0-9]perché altrimenti input come '%%%' falliranno. Ho anche aggiunto s/%/%%/galla fine per essere sicuro di sfuggire alle percentuali di printf.
josch,

1

Shell-only:

$ x='a%20%25%e3%81%82';printf "${x//\%/\\x}"
a %あ

Aggiungi --o %bper impedire che gli argomenti che iniziano con un trattino vengano trattati come opzioni.

In zsh ${x//%/a}aggiunge aalla fine ma ${x//\%/a}sostituisce %con a.


1

Ecco i bit rilevanti di un altro script (che ho appena spudoratamente rubato dal mio script di download di youtube.com da un'altra risposta) che ho scritto prima. Usa sede la shell per creare un codice urld funzionante.

set \! \" \# \$ \% \& \' \( \) \* \ \+ \, \/ \: \; \= \? \@ \[ \]
for c do set "$@" "'$c" "$c"; shift; done
curl -s "$url" | sed 's/\\u0026/\&/g;'"$(
    printf 's/%%%X/\\%s/g;' "$@"
)"

Non voglio giurare che sia esaustivo - e in effetti ne dubito - ma sicuramente ha gestito YouTube.


1

Ecco una funzione BASH per fare esattamente questo:

function urldecode() {
        echo -ne $(echo -n "$1" | sed -E "s/%/\\\\x/g")
}

funziona come per incanto
AbdElraouf Sabri,

0

Un'altra soluzione che utilizza ruby ​​(la risposta Python accettata non funzionava per me)

alias urldecode='ruby -e "require \"cgi\"; puts CGI.unescape(ARGV[0])"'
alias urlencode='ruby -e "require \"cgi\"; puts CGI.escape(ARGV[0])"'

Esempio

$ urldecode 'q+werty%3D%2F%3B'
q werty=/;

$ urlencode 'q werty=/;'
q+werty%3D%2F%3B
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.