Vreau să decodez codificarea URL, există vreun instrument încorporat pentru a face acest lucru sau cineva mi-ar putea furniza un sed
cod care va face acest lucru?
Am căutat puțin prin unix.stackexchange.com și pe internet, dar nu am găsit niciun instrument de linie de comandă pentru decodare codificare URL.
Ceea ce vreau să fac este pur și simplu să editați un fișier txt
astfel încât:
-
%21
devine!
-
%23
devine#
-
%24
devine$
-
%26
devine&
-
%27
devine"
-
%28
devine(
-
%29
devine)
Și așa mai departe.
Comentarii
- stackoverflow.com/questions/6250698/…
Răspuns
S-au găsit aceste linii Python one care fac ceea ce doriți:
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]))""
Exemplu
$ urldecode "q+werty%3D%2F%3B" q werty=/; $ urlencode "q werty=/;" q+werty%3D%2F%3B
Referințe
Comentarii
- Știu asta foarte târziu , dar există vreo modalitate prin care pot face acest lucru cu editarea în loc?
- @DisplayName – mi se pare un Q nou. ‘ l-aș întreba și îl refer la acesta.
- 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]"
- Consultați răspunsul @DIG mbl ‘ pentru a răspunde la unul care funcționează cu stdin.
Răspuns
sed
Încercați următoarea linie de comandă:
$ sed "s@+@ @g;s@%@\\x@g" file | xargs -0 printf "%b"
sau următoarea alternativă folosind echo -e
:
$ sed -e"s/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g" file | xargs echo -e
Notă: Sintaxa de mai sus nu poate converti +
în spații și pot mânca toate noile linii.
Puteți să-l definiți ca alias și să-l adăugați la fișierele dvs. shell rc :
$ alias urldecode="sed "s@+@ @g;s@%@\\\\x@g" | xargs -0 printf "%b""
Apoi, de fiecare dată când aveți nevoie, pur și simplu mergeți cu:
$ echo "http%3A%2F%2Fwww" | urldecode http://www
Bash
Atunci când creați scripturi, puteți utiliza următoarea sintaxă:
input="http%3A%2F%2Fwww" decoded=$(printf "%b" "${input//%/\\x}")
Cu toate acestea, sintaxa de mai sus a câștigat „t handle pluses 2b821b029a „>
) corect, deci trebuie să le înlocuiți cu spații prin
sed
sau după cum sugerează @isaac , utilizați următoarea sintaxă:
decoded=$(input=${input//+/ }; printf "${input//%/\\x}")
Puteți utiliza și următoarele funcții 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}" }
Rețineți că mai sus de
urldecode()
se presupune că datele nu conțin nicio bară inversă.
Iată versiunea similară a lui Joel găsită la: https://github.com/sixarm/urldecode.sh
bash + xxd
Funcția Bash cu instrumentul 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 }
Găsit în fișierul esențial cdown „, de asemenea la stackoverflow .
PHP
Folosind PHP puteți încerca următoarea comandă:
$ echo oil+and+gas | php -r "echo urldecode(fgets(STDIN));" // Or: php://stdin oil and gas
sau doar:
php -r "echo urldecode("oil+and+gas");"
Utilizați -R
pentru intrarea pe mai multe linii.
Perl
În Perl tu poate folosi URI::Escape
.
decoded_url=$(perl -MURI::Escape -e "print uri_unescape($ARGV[0])" "$encoded_url")
Sau pentru a procesa un fișier:
perl -i -MURI::Escape -e "print uri_unescape($ARGV[0])" file
awk
Încercați anon soluție:
awk -niord "{printf RT?$0chr("0x"substr(RT,2)):$0}" RS=%..
Notă: Parametrul -n
este specific GNU awk
.
A se vedea: Utilizarea awk printf pentru a codifica textul .
decodarea numelor fișierelor
Dacă trebuie să eliminați codificarea URL din numele fișierelor, utilizați instrumentul deurlname
din renameutils
(de ex deurlname *.*
).
Vezi și:
- Poate wget decoda uri numele fișierelor atunci când descărcați în lot?
- Cum se elimină codificarea URI din numele fișierelor?
În legătură:
- Cum se decodează șirul codat URL în shell? la SO
- Cum pot codifica și decoda șiruri codate procentual pe linia de comandă? la Ask Ubuntu
Comentarii
-
awk
: După cum se face acest lucru utilizarea unei funcții de bibliotecă,chr()
, există o mare probabilitate că va funcționa exclusiv pe GNU awk (gawk
). Cu toate acestea, în acest caz nu va exista aproape niciun echivalent pentru POSIXawk
, deoarece opțiunea-n
(permițând argumente non-zecimale) ESTE o specialitate GNUawk
. - Soluțiile dvs. care implică
printf
nu iau în considerare faptul că adresa URL poate conține semne procentuale evadate, cum ar fi%25
. Le treceți la printf fără a le scăpa pentru printf cu alt semn procentual ca%%
. - Versiunea bash necesită
local LC_ALL=C
în partea de sus, în caz contrar, toate caracterele largi (de exemplu, japoneze, chinezești etc.) nu sunt împărțite corect în octeți. - github.com/SixArm/ urlencode.sh
- Versiunile printf nu ‘ nu funcționează când se utilizează versiunea BSD a printf (de exemplu, macOS), totuși funcționează bine când se utilizează Versiunea GNU Coreutils.
Răspuns
Există o funcție încorporată pentru aceasta în biblioteca standard Python. În Python 2, este „s urllib.unquote
.
decoded_url=$(python2 -c "import sys, urllib; print urllib.unquote(sys.argv[1])" "$encoded_url")
Sau pentru a procesa un fișier:
python2 -c "import sys, urllib; print urllib.unquote(sys.stdin.read())" <file >file.new && mv -f file.new file
În Python 3, este „s urllib.parse.unquote
.
decoded_url=$(python3 -c "import sys, urllib.parse; print(urllib.parse.unquote(sys.argv[1]))" "$encoded_url")
Sau pentru a procesa un fișier:
python3 -c "import sys, urllib; print(urllib.parse.unquote(sys.stdin.read()))" <file >file.new && mv -f file.new file
În Perl puteți utiliza URI::Escape
.
decoded_url=$(perl -MURI::Escape -e "print uri_unescape($ARGV[0])" "$encoded_url")
Sau pentru a procesa un fișier:
perl -i -MURI::Escape -e "print uri_unescape($ARGV[0])" file
Dacă doriți să rămâneți la instrumentele portabile POSIX, acesta ” Este ciudat, deoarece singurul candidat serios este awk, care nu analizează numerele hexazecimale. Consultați Utilizarea awk printf pentru a codifica textul pentru exemple cu implementări obișnuite awk, inclusiv BusyBox.
Răspuns
Perl one liner:
$ perl -pe "s/\%(\w\w)/chr hex $1/ge"
Exemplu:
$ echo "%21%22" | perl -pe "s/\%(\w\w)/chr hex $1/ge" !"
Comentarii
- Acest răspuns este atractiv atunci când nu ‘ nu doriți să vă ocupați de instalarea modulelor perl.
- Doar unul care a funcționat elegant pentru mine pe MacOS.
- Dacă doriți să rezolvați toate nivelurile de codificare URL simultan, acolo ‘ De asemenea,
perl -pe 's/\%([[:xdigit:]]{2})/chr hex $1/ge while (/\%[[:xdigit:]]{2}/);'
care va decoda toate%25xx
codificări imbricate
Răspuns
Dacă doriți să utilizați o comandă simplă sed
, utilizați următoarele:
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"
Dar este mai convenabil să creați un script ca (spune sedscript
):
s/%21/!/g s/%23/#/g s/%24/$/g s/%26/\&/g s/%27/"/g s/%28/(/g s/%29/)/g
Apoi rulați sed -f sedscript < old > new
, care va ieși după cum doriți.
Pentru o ușurință, comanda urlencode
este de asemenea disponibilă direct în gridsite-clients
poate fi instalat de la (de sudo apt-get install gridsite-clients
în sistemul Ubuntu / Debian).
NAME
urlencode – convertiți șirurile în sau dintr-o formă codificată URL
SINOPSĂ
urlencode [-m|-d] string [string ...]
DESCRIERE
urlencode
codifică șiruri conform RFC 1738.Adică caractere
A
–Z
a
–z
0
–9
.
_
și-
sunt trecute nemodificate, dar toate celelalte caractere sunt reprezentate ca% HH, unde HH este a doua lor zi igit reprezentare ASCII hexazecimală cu majuscule. De exemplu, URL-ulhttp://www.gridpp.ac.uk/
devinehttp%3A%2F%2Fwww.gridpp.ac.uk%2F
urlencode
fiecare caracter din toate șirurile date pe linia de comandă. Dacă sunt date mai multe șiruri, acestea sunt concatenate cu spații separate înainte de conversie.OPȚIUNI
-m
În loc de conversie completă, faceți GridSite „codificare URL ușoară” în care AZ az 0-9. = – _ @ și / sunt trecute prin nemodificate. Acest lucru are ca rezultat șiruri ușor mai ușor de citit de către oameni, dar aplicația trebuie să fie pregătită pentru a crea sau simula directoarele implicate de orice bară.
-d
Faceți decodarea URL mai degrabă decât codificarea, conform RFC 1738.% HH și% hh șiruri sunt convertite și alte caractere sunt trecute nemodificate, cu excepția faptului că
+
este convertit în spațiu.
Exemplu de decodare URL:
$ urlencode -d "http%3a%2f%2funix.stackexchange.com%2f" http://unix.stackexchange.com/ $ urlencode -d "Example: %21, %22, . . . , %29 etc" Example: !, ", . . . , ) etc
Comentarii
- Pentru tutorial despre
sed
vizitați - Aceasta este o soluție proastă, deoarece necesită codificare hard pentru fiecare caracter. Această problemă este exemplificată de codul dvs. care lipsește
%20
secvența de evadare folosită. - @Overv I ‘ tocmai Revizuit
- De asemenea, vă recomandăm să verificați din nou ce face
s/%26/&/g
. (L-am remediat.)
Răspuns
Nu pot să comentez cel mai bun răspuns din acest fir , deci iată al meu.
Personal, folosesc aceste aliasuri pentru codificarea și decodarea adreselor 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])""
Ambele comenzi vă permit să convertiți date, transmise ca un argument linie de comandă sau să le citiți din intrare standard , deoarece ambele linii verifică dacă există argumente din linia de comandă (chiar și cele goale) și le procesează sau doar le citesc intrare standard în caz contrar.
actualizare 23.05.2017 (codare slash)
Ca răspuns la comentariul lui @Bevor.
Dacă De asemenea, trebuie să codificați slash-ul, trebuie doar să adăugați un al doilea argument gol la funcția de citat, apoi slash-ul va fi, de asemenea, codificat.
Deci, în cele din urmă urlencode
alias în bash arată astfel:
alias urlencode="python -c "import urllib, sys; print urllib.quote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1], \"\")""
Examen 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
Comentarii
- Nu codifică bare oblice.
- @Bevor : Exemplu?
- Adăugați o bară la codul URL ” Проба пера ” – > rezultat: Slash nu este codificat.
- @Bevor: Ai dreptate. Multumesc pentru comentariu. De asemenea, îmi voi schimba răspunsul pentru a reflecta comentariul dvs. în acesta.
Răspuns
GNU Awk
#!/usr/bin/awk -fn @include "ord" BEGIN { RS = "%.." } { printf "%s", $0 if (RT != "") { printf "%s", chr("0x" substr(RT, 2)) } }
Răspuns
Și o altă abordare Perl:
#!/usr/bin/env perl use URI::Encode; my $uri = URI::Encode->new( { encode_reserved => 0 } ); while (<>) { print $uri->decode($_) }
Va trebui să instalați modulul URI::Encode
. Pe Debian, aș putea pur și simplu să rulez
sudo apt-get install liburi-encode-perl
Apoi, am rulat scriptul de mai sus pe un fișier de testare care conține:
http://foo%21asd%23asd%24%26asd%27asd%28asd%29
Rezultatul a fost (salvasem scriptul ca foo.pl
):
$ ./foo.pl http://foo!asd#asd$&asd"asd(asd)
Răspuns
Un răspuns în shell (mai ales Posix):
$ input="%21%22" $ printf "`printf "%s\n" "$input" | sed -e "s/+/ /g" -e "s/%\(..\)/\\\\x\1/g"`" !"
Explicație:
-
-e "s/+/ /g
transformă fiecare+
în spațiu (așa cum este descris în norma de codificare URL) -
-e "s/%\(..\)/\\\\x\1/g"
transformă fiecare%XX
în\\xXX
. Observați că unul dintre\
va fi eliminat prin citarea regulilor. - Imprimarea interioară este doar acolo pentru a transmite intrarea către sed. Îl putem înlocui cu orice alt mecanism
- Printf exterior interpretează secvențele
\\xXX
și afișează rezultatul.
Editați:
Deoarece %
ar trebui întotdeauna interpretat în URL-uri, este posibil să simplificăm acest răspuns. În plus, cred că este mai curat să folosiți xargs
în loc de backquotes (datorită @josch).
$ input="%21%22+%25" $ printf "%s\n" "$input" | sed -e "s/+/ /g; s/%/\\x/g" | xargs -0 printf !" %
Din păcate, (așa cum a observat @josch) nici una dintre aceste soluții nu este compatibilă cu Posix, deoarece \x
secvența de evacuare nu este definită în Posix.
Comentarii
- Bine ați venit la U & L. Poate ai putea explica acest răspuns și cum funcționează. În general, preferăm ca răspunsurile noastre să fie de formă lungă, cu detalii, nu doar fragmente de cod.
- Îmi place foarte mult acest răspuns, deoarece ‘ este cuprinzător, portabil și nu ‘ t necesită programe externe mai grele, cum ar fi perl sau python. Funcționează bine pentru mine.
- Soluție excelentă. Și chiar mai scurt și mai inteligent:
... | sed 's/+/ /g;s/%\(..\)/\\\\x\1/g'
. Opțiunea-e
poate fi omisă de fapt aici … - @josch Ai dreptate,
printf
este un încorporat îndash
și nu ‘ nu recunoaște\x
care scapă. Puteți utiliza/usr/bin/printf
în loc deprintf
pentru a-l face să funcționeze. În mod normal, ar trebui să puteți utilizacommand printf
, dar se pare că nu funcționează așa cum ar trebui. Acesta continuă să utilizeze funcția încorporată. - @Jezz într-adevăr suportul pentru
\x
nu face parte din POSIX: pubs.opengroup.org / onlinepubs / 9699919799 / utilities / printf.html În timpul testelor mele am văzut o altă problemă. S-ar putea să doriți să înlocuiți..
regex cu[a-zA-Z0-9][a-zA-Z0-9]
, pentru că în caz contrar, introduceți ca ‘ %% % ‘ va eșua. Am adăugat, de asemenea,s/%/%%/g
la sfârșit pentru a mă asigura că scap procentajele pentru printf.
Răspuns
O altă soluție care utilizează ruby (răspunsul python acceptat nu funcționa pentru mine)
alias urldecode="ruby -e "require \"cgi\"; puts CGI.unescape(ARGV[0])"" alias urlencode="ruby -e "require \"cgi\"; puts CGI.escape(ARGV[0])""
Exemplu
$ urldecode "q+werty%3D%2F%3B" q werty=/; $ urlencode "q werty=/;" q+werty%3D%2F%3B
Comentarii
- Doar folosit pentru rubin, iar aceste declarații par mai mici. De asemenea, m-am schimbat în ARGF.read, astfel încât să-l pot introduce ca la multe alte utilitare!
Răspuns
Iată o funcție BASH pentru a face exact asta:
function urldecode() { echo -ne $(echo -n "$1" | sed -E "s/%/\\\\x/g") }
Comentarii
- funcționează ca farmecul
- Dacă doriți să convertiți
+
caractere în spații și nu generează niciun proces, puteți utiliza acest lucru:: "${1//+/ }" && echo -e "${_//%/\\x}"
Răspuns
Numai Shell:
$ x="a%20%25%e3%81%82";printf "${x//\%/\\x}" a %あ
Adăugare --
sau %b
pentru a împiedica tratarea ca opțiuni a argumentelor care încep cu o liniuță.
În zsh ${x//%/a}
adaugă a
la final, dar ${x//\%/a}
înlocuiește %
cu a
.
Răspuns
Iată biții relevanți dintr-un alt script (pe care tocmai l-am făcut cu nerușinare) furat din scriptul de descărcare youtube.com dintr-un alt răspuns) Am mai scris. Folosește sed
și shell-ul pentru a construi un cod de lucru funcțional.
set \! \" \# \$ \% \& \" \( \) \* \ \+ \, \/ \: \; \= \? \@ \[ \] for c do set "$@" ""$c" "$c"; shift; done curl -s "$url" | sed "s/\\u0026/\&/g;""$( printf "s/%%%X/\\%s/g;" "$@" )"
Nu jur că este cuprinzător – și, de fapt, mă îndoiesc – dar cu siguranță s-a descurcat suficient cu youtube.
Răspuns
Soluția simplă pentru șiruri scurte de (shell-ul este lentwww):
$ str="q+werty%3D%2F%3B" $ a=${str//+/ };printf "$(echo "${a//%/\\x}")\n" q werty=/;