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
- stackoverflow.com/questions/6250698/…
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ż:
- Może wget dekodować uri nazwy plików podczas pobierania zbiorczego?
- Jak usunąć kodowanie URI z nazw plików?
Powiązane:
- Jak zdekodować ciąg zakodowany w postaci adresu URL w powłoce? w SO
- Jak kodować i dekodować ciągi zakodowane w procentach w wierszu poleceń? w Ask Ubuntu
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 POSIXawk
, ponieważ opcja-n
(dopuszczająca argumenty inne niż dziesiętne) JEST specjalnością GNUawk
. - 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
A
–Z
a
–z
0
–9
.
_
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 URLhttp://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 wbudowanydash
i nie ' nie rozpoznaje znaków\x
. Aby to działało, możesz użyć/usr/bin/printf
zamiastprintf
. Zwykle powinno być możliwe użyciecommand 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=/;