Dekodowanie kodowania adresu URL (kodowanie procentowe)

Chcę zdekodować kodowanie adresu URL, czy istnieje jakieś wbudowane narzędzie do tego, czy ktoś mógłby mi dostarczyć sed kod, który to zrobi?

Przeszukałem trochę unix.stackexchange.com i internet, ale nie mogłem znaleźć żadnego narzędzia wiersza poleceń do dekodowania kodowanie adresów URL.

Chcę po prostu edytować plik txt tak, aby:

  • %21 staje się !
  • %23 staje się #
  • %24 staje się $
  • %26 staje się &
  • %27 staje się "
  • %28 staje się (
  • %29 staje się )

I tak dalej.

Komentarze

Odpowiedź

Znalazłem te Python one linery, które robią co chcesz:

Python2

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

Python3

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

Przykład

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

Referencje

Komentarze

  • Wiem to bardzo późno , ale czy jest jakiś sposób, abym mógł to zrobić za pomocą edycji w miejscu?
  • @DisplayName – brzmi dla mnie jak nowy Q. Pytam o to ' i odnoszę się do tego.
  • 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]"
  • Zobacz odpowiedź @DIG mbl ', aby znaleźć taką, która działa ze standardowym wejściem.

Odpowiedź

sed

Wypróbuj następujący wiersz poleceń:

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

lub następującą alternatywę, używając echo -e:

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

Uwaga: powyższa składnia może nie konwertować + do spacji i może zjadać wszystkie znaki nowej linii.


Możesz zdefiniować go jako alias i dodać do swojej powłoki pliki rc :

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

Następnie za każdym razem, gdy tego potrzebujesz, po prostu użyj:

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

Bash

Podczas tworzenia skryptów możesz użyć następującej składni:

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

Jednak powyższa składnia nie obsługuje plusów (+) poprawnie, więc należy je zastąpić spacjami za pośrednictwem sed lub zgodnie z sugestią @isaac , użyj następującej składni:

decoded=$(input=${input//+/ }; printf "${input//%/\\x}") 

Możesz także użyć następujących funkcji urlencode() i urldecode():

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

Zauważ, że powyżej urldecode() założono, że dane nie zawierają ukośnika odwrotnego.

Oto podobna wersja Joela znaleziona pod adresem: https://github.com/sixarm/urldecode.sh


bash + xxd

Funkcja Bash z narzędziem xxd:

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 } 

Znaleziono w pliku głównym cdown „, również w stackoverflow .


PHP

Używając PHP, możesz wypróbować następujące polecenie:

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

lub po prostu:

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

Użyj -R do wprowadzania wielu wierszy.


Perl

W Perlu ty może używać URI::Escape .

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

Lub aby przetworzyć plik:

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

awk

Wypróbuj anon rozwiązanie:

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

Uwaga: parametr -n jest specyficzny dla GNU awk.

Zobacz: Używanie awk printf do kodu urldecode .

dekodowanie nazw plików

Jeśli chcesz usunąć kodowanie adresu URL z nazw plików, użyj narzędzia deurlname z renameutils (np deurlname *.*).

Zobacz też:


Powiązane:

Komentarze

  • awk: To sprawia, że użycie funkcji bibliotecznej, chr(), istnieje duże prawdopodobieństwo, że będzie działać wyłącznie na GNU awk (gawk). Jednak w tym przypadku nie będzie prawie żadnego odpowiednika dla POSIX awk, ponieważ opcja -n (dopuszczająca argumenty inne niż dziesiętne) JEST specjalnością GNU awk.
  • Twoje rozwiązania obejmujące printf nie uwzględniają tego adres URL może zawierać znaki procentu ze zmianą znaczenia, takie jak %25. Przekazujesz je do printf bez zmiany znaczenia dla printf z innym znakiem procentu, takim jak %%.
  • Wersja bash wymaga local LC_ALL=C u góry, w przeciwnym razie wszystkie szerokie znaki (np. japoński, chiński itp.) nie są poprawnie dzielone na bajty.
  • github.com/SixArm/ urlencode.sh
  • Wersje printf nie ' nie działają z wersją printf BSD (np. macOS), jednak działa dobrze, gdy używa się Wersja GNU Coreutils.

Odpowiedź

W standardowej bibliotece Pythona jest do tego wbudowana funkcja. W Pythonie 2 jest to urllib.unquote .

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

Lub aby przetworzyć plik:

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

W Pythonie 3 jest to urllib.parse.unquote .

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

Lub w celu przetworzenia pliku:

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

W Perlu możesz użyć URI::Escape .

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

Lub w celu przetworzenia pliku:

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

Jeśli chcesz trzymać się przenośnych narzędzi POSIX, to ” jest niezręczne, ponieważ jedynym poważnym kandydatem jest awk, który nie analizuje liczb szesnastkowych. Zobacz Używanie awk printf do kodu urldecode , aby zapoznać się z przykładami z typowymi implementacjami awk, w tym BusyBox.

Answer

Perl one liner:

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

Przykład:

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

Komentarze

  • Ta odpowiedź jest atrakcyjna, gdy nie ' nie chcesz zajmować się instalowaniem modułów Perla.
  • Tylko taki, który działał elegancko dla mnie na MacOS.
  • Jeśli chcesz rozwiązać wszystkie poziomy kodowania adresów URL na raz, ' s także perl -pe 's/\%([[:xdigit:]]{2})/chr hex $1/ge while (/\%[[:xdigit:]]{2}/);', który zdekoduje wszystkie %25xx zagnieżdżone kodowania

Odpowiedź

Jeśli chcesz użyć prostego polecenia sed, użyj następującego:

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" 

Ale wygodniej jest utworzyć skrypt, taki jak (powiedzmy sedscript):

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

Następnie uruchom sed -f sedscript < old > new, co spowoduje wyświetlenie zgodnie z oczekiwaniami.


Dla ułatwienia polecenie urlencode jest również dostępne bezpośrednio w gridsite-clients można zainstalować z (przez sudo apt-get install gridsite-clients w systemie Ubuntu / Debian).

NAZWA

    kod urlen – konwertuj ciągi do lub z postaci zakodowanej w adresie URL

SKŁADNIA

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

OPIS

    urlencode koduje ciągi zgodnie z RFC 1738.

    To znaczy znaki AZ az 09 . _ i - są przekazywane bez modyfikacji, ale wszystkie inne znaki są reprezentowane jako% HH, gdzie HH jest ich dwójką igit, wielka szesnastkowa reprezentacja ASCII. Na przykład adres URL http://www.gridpp.ac.uk/ staje się http%3A%2F%2Fwww.gridpp.ac.uk%2F

    urlencode konwertuje każdy znak we wszystkich napisach podanych w linii poleceń. Jeśli podanych jest wiele ciągów, są one łączone ze spacjami oddzielającymi przed konwersją.

OPCJE

    -m

      Zamiast pełnej konwersji wykonaj GridSite „łagodne kodowanie adresu URL” w którym AZ az 0-9. = – _ @ i / są przekazywane przez niezmodyfikowane. Powoduje to nieco bardziej czytelne dla człowieka ciągi, ale aplikacja musi być przygotowana do tworzenia lub symulacji katalogów wskazanych przez ukośniki.

    -d

      Zamiast dekodować adresy URL niż kodowanie, zgodnie z RFC 1738. Ciągi% HH i% hh są konwertowane, a inne znaki są przepuszczane przez niezmodyfikowane, z wyjątkiem tego, że + jest konwertowane na spację.

Przykład dekodowania adresu URL:

$ urlencode -d "http%3a%2f%2funix.stackexchange.com%2f" http://unix.stackexchange.com/ $ urlencode -d "Example: %21, %22, . . . , %29 etc" Example: !, ", . . . , ) etc 

Komentarze

  • Samouczek dotyczący sed odwiedź
  • To złe rozwiązanie, ponieważ wymaga zakodowania każdego znaku. Przykładem tego problemu jest brak w kodzie często używanej sekwencji ucieczki %20.
  • @Overv I ' ve po prostu Poprawiony
  • Możesz również dokładnie sprawdzić, co robi s/%26/&/g. (Naprawiłem to.)

Odpowiedź

Nie mogę komentować najlepsza odpowiedź w tym wątku , więc oto moja.

Osobiście używam tych aliasów do kodowania i dekodowania adresów 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])"" 

Oba polecenia pozwalają na konwersję danych, przekazanych jako argument wiersza poleceń lub odczytanie z standardowe wejście , ponieważ obie jednowierszowe linie sprawdzają, czy są argumenty wiersza poleceń (nawet puste) i przetwarzają je lub po prostu odczytują w przeciwnym razie standardowe wejście.


aktualizacja 2017-05-23 (kodowanie z ukośnikiem)

W odpowiedzi na komentarz @Bevor.

Jeśli również trzeba zakodować ukośnik, po prostu dodaj pusty drugi argument do funkcji cytowania, a następnie ukośnik również zostanie zakodowany.

Na koniec urlencode alias w bash wygląda tak:

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

Egzamin ple

$ 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 

Komentarze

  • Nie koduje ukośników.
  • @Bevor : Przykład?
  • Dodaj ukośnik do urlencode ” Проба пера ” – > wynik: ukośnik nie jest zakodowany.
  • @Bevor: Masz rację. Dziękuję za Twój komentarz. Zmienię również swoją odpowiedź, aby odzwierciedlić w niej Twój komentarz.

Odpowiedź

GNU Awk

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

Odpowiedź

I jeszcze jedno podejście w Perlu:

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

Będziesz musiał zainstalować moduł URI::Encode. Na moim Debianie mogłem po prostu uruchomić

sudo apt-get install liburi-encode-perl 

Następnie uruchomiłem powyższy skrypt na pliku testowym zawierającym:

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

Wynik był (zapisałem skrypt jako foo.pl):

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

Odpowiedź

Odpowiedź w powłoce (głównie Posix):

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

Wyjaśnienie:

  • przekształca każdy + w przestrzeń (zgodnie z opisem w normie kodowania adresów URL)
  • -e "s/%\(..\)/\\\\x\1/g" przekształć każdy %XX w \\xXX. Zauważ, że jeden z \ zostanie usunięty przez cytowanie reguł.
  • Wewnętrzny printf służy tylko do przekazywania danych wejściowych do seda. Możemy zastąpić go dowolnym innym mechanizmem.
  • Zewnętrzny printf interpretuje \\xXX sekwencje i wyświetla wynik.

Edycja:

Ponieważ % powinno być zawsze interpretowane w adresach URL, można uprościć tę odpowiedź. Ponadto wydaje mi się, że bardziej przejrzyste jest użycie xargs zamiast odwrotnych cudzysłowów (dzięki @josch).

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

Niestety (jak zauważył @josch) żadne z tych rozwiązań nie jest zgodne z Posix, ponieważ \x sekwencja ucieczki nie jest zdefiniowana w Posix.

Komentarze

  • Witamy w U & L. Być może mógłbyś wyjaśnić tę odpowiedź i jak to działa. Generalnie wolimy, aby nasze odpowiedzi były długie i zawierały szczegółowe informacje, a nie tylko fragmenty kodu.
  • Bardzo podoba mi się ta odpowiedź, ponieważ ' jest wszechstronna, przenośna i nie ' t wymaga dodatkowych, cięższych programów zewnętrznych, takich jak perl czy python. U mnie działa dobrze.
  • Świetne rozwiązanie. A nawet krótszy i sprytniejszy: ... | sed 's/+/ /g;s/%\(..\)/\\\\x\1/g'. W rzeczywistości opcję -e można tutaj pominąć …
  • @josch Masz rację, printf to wbudowany dash i nie ' nie rozpoznaje znaków \x. Aby to działało, możesz użyć /usr/bin/printf zamiast printf. Zwykle powinno być możliwe użycie command printf, ale wydaje się, że nie działa tak, jak powinno. Nadal używa wbudowanego.
  • @Jezz rzeczywiście obsługuje \x znaki ucieczki nie są częścią POSIX: pubs.opengroup.org / onlinepubs / 9699919799 / utilities / printf.html Podczas moich testów zauważyłem inny problem. Możesz zamienić swoje .. wyrażenie regularne na [a-zA-Z0-9][a-zA-Z0-9], ponieważ w przeciwnym razie wpisz ' %% % ' nie powiedzie się. Dodałem również s/%/%%/g na końcu, aby upewnić się, że zmienisz wartości procentowe dla printf.

Odpowiedź

Inne rozwiązanie wykorzystujące ruby (zaakceptowana odpowiedź Pythona nie działała dla mnie)

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

Przykład

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

Komentarze

  • Po prostu użyłem ruby, a te stwierdzenia wyglądają na mniejsze. Zmieniłem też na ARGF.read, więc mogę to zrobić tak, jak w przypadku wielu innych narzędzi!

Odpowiedź

Oto funkcja BASH, która dokładnie to robi:

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

Komentarze

  • działa jak urok
  • Jeśli chcesz przekonwertować + znaki na spacje i nie odradzają żadnych procesów, możesz użyć tego: : "${1//+/ }" && echo -e "${_//%/\\x}"

Odpowiedź

Tylko powłoka:

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

Dodaj -- lub %b, aby argumenty zaczynające się od myślnika nie były traktowane jako opcje.

W zsh ${x//%/a} dodaje a na końcu, ale ${x//\%/a} zamienia % na a.

Odpowiedź

Oto odpowiednie fragmenty z innego skryptu (który bezwstydnie ukradłem z mojego skryptu pobierania youtube.com z innej odpowiedzi) napisałem wcześniej. Używa sed i powłoki do zbudowania działającego kodu urldecode.

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

Przysięgam, że to wyczerpujące – i właściwie wątpię – ale na pewno poradził sobie z youtube.

Odpowiedź

Proste rozwiązanie dla krótkie ciągi (powłoka jest wolna):

$ str="q+werty%3D%2F%3B" $ a=${str//+/ };printf "$(echo "${a//%/\\x}")\n" q werty=/; 

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *