Dekodierung URL-Kodierung (Prozent-Kodierung)


100

Ich möchte die URL-Codierung decodieren. Gibt es ein eingebautes Tool dafür oder könnte mir jemand einen sedCode zur Verfügung stellen, der dies erledigt?

Ich habe ein bisschen unter unix.stackexchange.com und im Internet gesucht, aber ich konnte kein Befehlszeilentool zum Dekodieren der URL-Kodierung finden.

Was ich tun möchte, ist einfach vor Ort eine txtDatei zu bearbeiten , so dass:

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

Und so weiter.


Antworten:


107

Wir haben diese Python One-Liner gefunden, die genau das tun, was Sie wollen:

$ 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])"'

Beispiel

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

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

Verweise


Ich weiß das sehr spät, aber gibt es eine Möglichkeit, wie ich das mit der direkten Bearbeitung machen kann?
DisplayName

@DisplayName - klingt für mich wie ein neues Q. Ich würde es fragen und auf dieses verweisen.
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
Beachten Sie, dass dies ein Python 2 ist; Auf Systemen, auf denen pythonstandardmäßig 3 eingestellt ist, führt dies zu Fehlern. Wechseln pythonzu python2hilft.
Ivan Kolmychek

4
Denn python3Sie können import urllib.parse as ulanstelle von verwenden import urllib as ul.
iBotty

61

sed

Versuchen Sie die folgende Befehlszeile:

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

oder die folgende Alternative mit echo -e:

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

Hinweis: Die obige Syntax wird möglicherweise nicht +in Leerzeichen konvertiert und kann alle Zeilenumbrüche aufnehmen.


Sie können es als Alias ​​definieren und zu Ihren Shell- RC- Dateien hinzufügen :

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

Dann gehen Sie jedes Mal, wenn Sie es brauchen, einfach mit:

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

Bash

Bei der Skripterstellung können Sie die folgende Syntax verwenden:

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

Die obige Syntax behandelt Pluszeichen ( +) jedoch nicht korrekt, sodass Sie sie durch Leerzeichen über ersetzen müssen sed.

Sie können auch die folgenden verwenden urlencode()und urldecode()Funktionen:

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}"
}

Beachten Sie, dass oben urldecode()davon ausgegangen wird, dass die Daten keinen Backslash enthalten.

Hier finden Sie eine ähnliche Joel-Version: https://github.com/sixarm/urldecode.sh


bash + xxd

Bash-Funktion mit xxdTool:

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
}

Gefunden in der Hauptdatei von cdown , auch bei stackoverflow .


PHP

Mit PHP können Sie den folgenden Befehl versuchen:

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

oder nur:

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

Verwendung -Rfür mehrzeilige Eingabe.


Perl

In Perl können Sie verwenden URI::Escape.

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

Oder um eine Datei zu verarbeiten:

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

awk

Versuchen Sie eine andere Lösung:

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

Hinweis: Der Parameter -nist spezifisch für GNU awk.

Siehe: Verwenden von awk printf zum URL-Code von Text .

Dateinamen entschlüsseln

Wenn Sie die URL-Codierung aus den Dateinamen entfernen müssen, verwenden Sie das deurlnameTool von renameutils(z deurlname *.*. B. ).

Siehe auch:


Verbunden:


1
awk: Da dies eine Bibliotheksfunktion nutzt chr(), besteht eine hohe Wahrscheinlichkeit, dass sie nur auf GNU awk ( gawk) funktioniert . In diesem Fall wird es jedoch kaum für POSIX jeden gleichwertig sein awk, weil die -nOption (so dass nichtdezimale Argumente) IST eine GNU - awkSpezialität.
Syntaxfehler

Ihr erster sedCode gibt mir xargs: argument line too longeine Datei mit ≥2164 Zeilen.
Sparhawk

2
Bei Ihren Lösungen mit wird printfnicht berücksichtigt, dass die URL möglicherweise Prozentzeichen wie "Escape" enthält %25. Sie übergeben diese an printf, ohne sie für printf mit einem anderen Prozentzeichen wie zu maskieren %%.
Josef

1
Die Bash-Version erfordert local LC_ALL=Coben, sonst werden alle breiten Zeichen (z. B. Japanisch, Chinesisch usw.) nicht richtig in Bytes aufgeteilt.
Phernost


18

Dafür gibt es in der Python-Standardbibliothek eine integrierte Funktion. In Python 2 ist es urllib.unquote.

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

Oder um eine Datei zu verarbeiten:

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

In Python 3 ist es urllib.parse.unquote.

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

Oder um eine Datei zu verarbeiten:

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

In Perl können Sie verwenden URI::Escape.

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

Oder um eine Datei zu verarbeiten:

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

Wenn Sie sich an tragbare POSIX-Tools halten möchten, ist dies umständlich, da awk der einzige ernsthafte Kandidat ist, der keine hexadezimalen Zahlen parst. Siehe Verwenden von awk printf Text urldecode für Beispiele mit gemeinsamen awk - Implementierungen, einschließlich BusyBox.


10

Wenn Sie einen einfachen sedBefehl verwenden möchten, verwenden Sie Folgendes:

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'

Es ist jedoch praktischer, ein Skript wie das folgende zu erstellen sedscript:

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

Führen sed -f sedscript < old > newSie dann die gewünschte Ausgabe aus.


Zur Erleichterung ist der Befehl urlencodeauch direkt im gridsite-clientsPaket verfügbar , von dem aus ( sudo apt-get install gridsite-clientsin Ubuntu / Debian-System) installiert werden kann .

NAME

    urlencode - konvertiert Zeichenfolgen in oder aus einer URL-codierten Form
ZUSAMMENFASSUNG

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

BESCHREIBUNG

    urlencode codiert Zeichenfolgen gemäß RFC 1738.

    Das heißt, die Zeichen A- Z a- z 0- 9 . _und -werden unverändert weitergeleitet, alle anderen Zeichen werden jedoch als% HH dargestellt, wobei HH die zweistellige hexadezimale ASCII-Darstellung in Großbuchstaben ist. Zum Beispiel kann die URL http://www.gridpp.ac.uk/wirdhttp%3A%2F%2Fwww.gridpp.ac.uk%2F

    urlencodekonvertiert jedes Zeichen in alle Zeichenfolgen, die in der Befehlszeile angegeben sind. Wenn mehrere Zeichenfolgen angegeben sind, werden diese vor der Konvertierung mit Leerzeichen verknüpft.

OPTIONEN
    -m
      Verwenden Sie anstelle der vollständigen Konvertierung die "milde URL-Codierung" von GridSite mit AZ az 0-9. = - _ @ und / werden unverändert durchgereicht. Dies führt zu etwas besser lesbaren Zeichenfolgen, aber die Anwendung muss darauf vorbereitet sein, die durch Schrägstriche implizierten Verzeichnisse zu erstellen oder zu simulieren.
    -d
      Führen Sie gemäß RFC 1738 eher eine URL-Dekodierung als eine Kodierung durch.% HH- und% hh-Zeichenfolgen werden konvertiert und andere Zeichen werden unverändert weitergeleitet, mit der Ausnahme, dass +sie in Leerzeichen konvertiert werden.

Beispiel für die Dekodierung einer URL:

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

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

Für Tutorial auf sed Besuch
Pandya

4
Dies ist eine schlechte Lösung, da jedes Zeichen hartcodiert werden muss. Dieses Problem wird durch Ihren Code veranschaulicht, dem die häufig verwendete %20Escape-Sequenz fehlt .
Overv

@Overv Ich habe gerade überarbeitet
Pandya

Vielleicht möchten Sie auch noch einmal überprüfen, was s/%26/&/ggeschieht. (Ich habe es behoben.)
G-Man

9

Perl Einzeiler:

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

Beispiel:

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

1
Diese Antwort ist attraktiv, wenn Sie sich nicht mit der Installation von Perl-Modulen befassen möchten.
Sridhar Sarnobat

1
Nur eines, das für mich unter MacOS elegant funktioniert hat.
Qix


7

Ich kann die beste Antwort in diesem Thread nicht kommentieren , also hier meine.

Persönlich verwende ich diese Aliase für die URL-Codierung und -Decodierung:

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])"'

Mit beiden Befehlen können Sie Daten konvertieren, die als Befehlszeilenargument übergeben oder von der Standardeingabe gelesen wurden , da beide Einzeilen prüfen, ob Befehlszeilenargumente (auch leere) vorhanden sind, und diese verarbeiten oder die Standardeingabe einfach anderweitig lesen.


Update 23.05.2017 (Schrägstrichcodierung)

Als Antwort auf den Kommentar von @ Bevor.

Wenn Sie auch den Schrägstrich codieren müssen, fügen Sie der Anführungszeichenfunktion einfach ein leeres zweites Argument hinzu. Der Schrägstrich wird dann ebenfalls codiert.

Der urlencode Alias in der Bash sieht also so aus:

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

Beispiel

$ 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
Codiert keine Schrägstriche.
Vor

@Bevor: Beispiel?
DIG mbl

Fügen Sie dem Urlencode "Проба пера" einen Schrägstrich hinzu -> Ergebnis: Der Schrägstrich wird nicht codiert.
Vor

1
@Bevor: Du hast recht. Danke für deinen Kommentar. Ich werde auch meine Antwort ändern, um Ihren Kommentar darin widerzuspiegeln.
DIG mbl

4

Und noch ein Perl-Ansatz:

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

    print $uri->decode($_)
}

Sie müssen das URI::EncodeModul installieren . Auf meinem Debian konnte ich einfach laufen

sudo apt-get install liburi-encode-perl

Dann habe ich das obige Skript für eine Testdatei ausgeführt, die Folgendes enthält:

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

Das Ergebnis war (ich hatte das Skript gespeichert als foo.pl):

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

3

Eine Antwort in (meistens Posix) Shell:

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

Erläuterung:

  • -e 's/+/ /gtransformiert jedes +im Raum (wie in der url-encode Norm beschrieben)
  • -e 's/%\(..\)/\\\\x\1/g'transformiere jeden %XXin \\xXX. Beachten Sie, dass einer von \durch Anführungszeichen entfernt wird.
  • Das innere printf ist nur dazu da, Eingaben an sed weiterzuleiten. Wir können es durch einen anderen Mechanismus ersetzen
  • Der äußere Ausdruck interpretiert die \\xXXSequenzen und zeigt das Ergebnis an.

Bearbeiten:

Da %in URLs immer interpretiert werden sollte, ist es möglich, diese Antwort zu vereinfachen. Außerdem halte ich es für sauberer, xargsanstelle von Backquotes zu verwenden (danke an @josch).

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

Leider (wie @josch bemerkt hat) ist keine dieser Lösungen Posix-kompatibel, da die \xEscape-Reihenfolge in Posix nicht definiert ist.


Willkommen bei U & L. Vielleicht könntest du diese Antwort erklären und wie es funktioniert. Wir bevorzugen im Allgemeinen lange Antworten mit Details, nicht nur Code-Schnipsel.
slm

Ich mag diese Antwort wirklich, weil sie umfassend und portabel ist und keine zusätzlichen externen Programme wie Perl oder Python erfordert. Funktioniert gut für mich.
Steve Wills

1
Großartige Lösung. Und noch kürzer und intelligenter: ... | sed 's/+/ /g;s/%\(..\)/\\\\x\1/g'. Die -eOption kann hier in der Tat weggelassen werden ...
Syntaxfehler

1
@josch Du hast recht, printfist ein eingebautes dashund es erkennt kein \xEntkommen. Sie können /usr/bin/printfanstelle von printfverwenden, damit es funktioniert. Normalerweise sollten Sie verwenden können command printf, aber es scheint nicht so zu funktionieren, wie es sollte. Es weiterhin eingebaute verwenden.
Jérôme Pouiller

1
@ Jezz-Unterstützung für \xFlucht ist in der Tat kein Bestandteil von POSIX: pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html Während meiner Tests habe ich ein anderes Problem festgestellt . Möglicherweise möchten Sie Ihre ..Regex durch ersetzen, [a-zA-Z0-9][a-zA-Z0-9]da andernfalls Eingaben wie '%%%' fehlschlagen. Ich habe auch s/%/%%/gam Ende hinzugefügt , um sicherzustellen, dass Prozentsätze für printf nicht angezeigt werden.
josch

1

Nur Shell:

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

Fügen Sie --oder hinzu %b, um zu verhindern, dass Argumente, die mit einem Bindestrich beginnen, als Optionen behandelt werden.

In zsh ${x//%/a}fügt aan das Ende , sondern ${x//\%/a}ersetzt %mit a.


1

Hier sind die relevanten Teile aus einem anderen Skript (das ich schamlos aus meinem youtube.com-Download-Skript aus einer anderen Antwort gestohlen habe ), die ich zuvor geschrieben habe. Es benutzt sedund die Shell, um einen funktionierenden URL-Code aufzubauen.

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

Ich werde nicht schwören, dass es umfassend ist - und tatsächlich bezweifle ich es -, aber es hat mit Sicherheit genug mit YouTube zu tun.


1

Hier ist eine BASH-Funktion, um genau das zu tun:

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

funktioniert wie Charme
AbdElraouf Sabri

0

Eine andere Lösung mit Ruby (akzeptierte Python-Antwort hat bei mir nicht funktioniert)

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

Beispiel

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

$ urlencode 'q werty=/;'
q+werty%3D%2F%3B
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.