Chci dekódovat kódování URL, existuje k tomu nějaký vestavěný nástroj nebo mi někdo může poskytnout sed
kód, který to udělá?
Trochu jsem prohledával unix.stackexchange.com a na internetu, ale nenašel jsem žádný nástroj příkazového řádku pro dekódování kódování URL.
To, co chci udělat, je jednoduše na místě upravit soubor txt
tak, aby:
-
%21
se stává!
-
%23
#
-
%24
se stává$
-
%26
se stává&
-
%27
se stává"
-
%28
se stává(
-
%29
stává se)
atd.
Komentáře
- stackoverflow.com/questions/6250698/…
Odpověď
Nalezli tyto vložky Pythonu, které dělají, co chcete:
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]))""
Příklad
$ urldecode "q+werty%3D%2F%3B" q werty=/; $ urlencode "q werty=/;" q+werty%3D%2F%3B
Reference
Komentáře
- Vím to velmi pozdě , ale existuje nějaký způsob, jak to udělat s úpravami na místě?
- @DisplayName – zní mi to jako nové Q. ‚ Požádám o to a odkazuji na tento.
- streamování:
cat your_lovely_file.csv| python -c "import sys, urllib as ul; [sys.stdout.write(ul.quote_plus(l)) for l in sys.stdin]"
- Viz odpověď @DIG mbl ‚ na odpověď, která funguje se stdin.
Odpověď
sed
Zkuste následující příkazový řádek:
$ sed "s@+@ @g;s@%@\\x@g" file | xargs -0 printf "%b"
nebo následující alternativu pomocí echo -e
:
$ sed -e"s/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g" file | xargs echo -e
Poznámka: Výše uvedená syntaxe nemusí převádět +
do mezer a může pojmout všechny nové řádky.
Můžete jej definovat jako alias a přidat jej do svých rc souborů:
$ alias urldecode="sed "s@+@ @g;s@%@\\\\x@g" | xargs -0 printf "%b""
Pak pokaždé, když to potřebujete, jednoduše použijte:
$ echo "http%3A%2F%2Fwww" | urldecode http://www
Bash
Při skriptování můžete použít následující syntaxi:
input="http%3A%2F%2Fwww" decoded=$(printf "%b" "${input//%/\\x}")
Výše uvedená syntaxe však nevyřeší klady (+
) správně, takže je můžete nahradit mezerami pomocí sed
nebo podle doporučení @isaac použijte následující syntaxi:
decoded=$(input=${input//+/ }; printf "${input//%/\\x}")
Můžete také použít následující urlencode()
a urldecode()
funkce:
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}" }
Všimněte si, že výše
urldecode()
předpokládá, že data neobsahují žádné zpětné lomítko.
Zde je podobná verze Joela nalezená na adrese: https://github.com/sixarm/urldecode.sh
bash + xxd
Bash funkce s nástrojem 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 }
Nalezeno v cdown „s hlavním souborem , také na stackoverflow .
PHP
Pomocí PHP můžete vyzkoušet následující příkaz:
$ echo oil+and+gas | php -r "echo urldecode(fgets(STDIN));" // Or: php://stdin oil and gas
nebo jen:
php -r "echo urldecode("oil+and+gas");"
Použijte -R
pro víceřádkový vstup.
Perl
V Perlu vy může používat URI::Escape
.
decoded_url=$(perl -MURI::Escape -e "print uri_unescape($ARGV[0])" "$encoded_url")
Nebo zpracovat soubor:
perl -i -MURI::Escape -e "print uri_unescape($ARGV[0])" file
awk
Zkuste anon řešení:
awk -niord "{printf RT?$0chr("0x"substr(RT,2)):$0}" RS=%..
Poznámka: Parametr -n
je specifický pro GNU awk
.
Viz: Použití awk printf k urldekódování textu .
dekódování názvů souborů
Pokud potřebujete odstranit kódování adres URL z názvů souborů, použijte nástroj deurlname
z renameutils
(např deurlname *.*
).
Viz také:
- Může dekódovat uri názvy souborů při hromadném stahování?
- Jak odstranit kódování URI z názvů souborů?
Související:
- Jak dekódovat řetězec kódovaný URL ve skořápce? v SO
- Jak mohu na příkazovém řádku kódovat a dekódovat řetězce kódované v procentech? na stránce Zeptejte se Ubuntu
Komentáře
-
awk
: Díky tomu při použití funkce knihovnychr()
je vysoká pravděpodobnost, že bude fungovat pouze na GNU awk (gawk
). V tomto případě však pro POSIXawk
téměř neexistuje ekvivalent, protože možnost-n
(umožňující nedesítkové argumenty) JE specialita GNUawk
. - Vaše řešení zahrnující
printf
nebere v úvahu, že adresa URL může obsahovat znaky procenta s únikem, například%25
. Předáte je printf, aniž byste je unikli pro printf s jiným znakem procenta, jako je%%
. - Verze bash vyžaduje
local LC_ALL=C
nahoře, jinak nebudou všechny široké znaky (tj. japonské, čínské atd.) správně rozděleny na bajty. - github.com/SixArm/ urlencode.sh
- Verze printf nefungují ‚ při použití BSD verze printf (např. macOS), ale při použití Verze GNU Coreutils.
Odpověď
Ve standardní knihovně Pythonu je k tomu integrovaná funkce. V Pythonu 2 je to „s urllib.unquote
.
decoded_url=$(python2 -c "import sys, urllib; print urllib.unquote(sys.argv[1])" "$encoded_url")
Nebo zpracovat soubor:
python2 -c "import sys, urllib; print urllib.unquote(sys.stdin.read())" <file >file.new && mv -f file.new file
V Pythonu 3 je to „s urllib.parse.unquote
.
decoded_url=$(python3 -c "import sys, urllib.parse; print(urllib.parse.unquote(sys.argv[1]))" "$encoded_url")
Nebo zpracovat soubor:
python3 -c "import sys, urllib; print(urllib.parse.unquote(sys.stdin.read()))" <file >file.new && mv -f file.new file
V Perlu můžete použít URI::Escape
.
decoded_url=$(perl -MURI::Escape -e "print uri_unescape($ARGV[0])" "$encoded_url")
Nebo zpracovat soubor:
perl -i -MURI::Escape -e "print uri_unescape($ARGV[0])" file
Pokud se chcete držet přenosných nástrojů POSIX, je to “ je to trapné, protože jediný vážný kandidát je awk, který nerozebere hexadecimální čísla. Příklady s běžnými implementacemi awk, včetně BusyBox, najdete v části Použití awk printf k urldecode textu .
Odpovědět
Perl jedna linka:
$ perl -pe "s/\%(\w\w)/chr hex $1/ge"
Příklad:
$ echo "%21%22" | perl -pe "s/\%(\w\w)/chr hex $1/ge" !"
Komentáře
- Tato odpověď je atraktivní, pokud se nechcete ‚ zabývat instalací modulů Perl.
- Pouze jeden, který pro mě v systému MacOS fungoval elegantně.
- Pokud chcete vyřešit všechny úrovně kódování adres URL najednou, existuje ‚ s také
perl -pe 's/\%([[:xdigit:]]{2})/chr hex $1/ge while (/\%[[:xdigit:]]{2}/);'
který dekóduje všechna%25xx
vnořená kódování
odpověď
Pokud chcete použít jednoduchý sed
příkaz, použijte následující:
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"
Je však pohodlnější vytvořit skript jako (řekněme sedscript
):
s/%21/!/g s/%23/#/g s/%24/$/g s/%26/\&/g s/%27/"/g s/%28/(/g s/%29/)/g
Poté spusťte program sed -f sedscript < old > new
, který se bude zobrazovat podle vašich požadavků.
Pro usnadnění je příkaz urlencode
k dispozici také přímo v gridsite-clients
balíček lze nainstalovat z (pomocí sudo apt-get install gridsite-clients
v systému Ubuntu / Debian).
NAME
urlencode – převádí řetězce do nebo z formuláře kódovaného URL
SYNOPSIS
urlencode [-m|-d] string [string ...]
POPIS
urlencode
kóduje řetězce podle RFC 1738.To znamená, znaky
A
–Z
a
–z
0
–9
.
_
a-
procházejí nezměněnými, ale všechny ostatní znaky jsou reprezentovány jako% HH, kde HH je jejich dvojd igit velká hexadecimální reprezentace ASCII. Například adresa URLhttp://www.gridpp.ac.uk/
se změní nahttp%3A%2F%2Fwww.gridpp.ac.uk%2F
urlencode
každý znak ve všech řetězcích uvedených na příkazovém řádku. Pokud je zadáno více řetězců, jsou před převodem zřetězeny oddělujícími mezerami.MOŽNOSTI
-m
Místo úplné konverze proveďte GridSite „mírné kódování URL“ ve kterém AZ az 0-9. = – _ @ a / jsou předávány beze změny. Výsledkem jsou o něco více čitelné řetězce, ale aplikace musí být připravena vytvořit nebo simulovat adresáře implikované lomítky.
-d
Provádějte spíše dekódování URL než kódování, podle RFC 1738. Řetězce% HH a% hh jsou převedeny a ostatní znaky procházejí nezměněnými, s výjimkou, že
+
je převeden na mezeru.
Příklad dekódovací adresy URL:
$ urlencode -d "http%3a%2f%2funix.stackexchange.com%2f" http://unix.stackexchange.com/ $ urlencode -d "Example: %21, %22, . . . , %29 etc" Example: !, ", . . . , ) etc
Komentáře
- Výukový program k
sed
návštěvě - Toto je špatné řešení, protože vyžaduje pevné zakódování každého znaku. Příkladem tohoto problému je, že ve vašem kódu chybí často používaná
%20
úniková sekvence. - @Overv I ‚ jsem jen Upraveno
- Možná budete chtít ještě jednou zkontrolovat, co
s/%26/&/g
dělá. (Opravil jsem to.)
Odpovědět
Nemohu komentovat nejlepší odpověď v tomto vlákně , takže tady je moje.
Osobně používám tyto aliasy pro kódování a dekódování 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 příkazy umožňují převádět data, předávaná jako argument příkazového řádku nebo číst z standardní vstup , protože obě řádky kontrolují, zda existují argumenty příkazového řádku (i prázdné), a zpracovávají je nebo jen čtou jinak standardní vstup.
aktualizace 2017-05-23 (kódování lomítka)
v reakci na komentář @Bevor.
pokud také je třeba kódovat lomítko, stačí přidat prázdný druhý argument do funkce citace, poté se lomítko také zakóduje.
Takže nakonec urlencode
alias v bash vypadá takto:
alias urlencode="python -c "import urllib, sys; print urllib.quote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1], \"\")""
zkouška 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
Komentáře
- Nekóduje lomítka.
- @Bevor : Příklad?
- Přidat lomítko do urlencode “ Проба пера “ – > výsledek: Slash není zakódován.
- @Bevor: Máte pravdu. Děkuji za váš komentář. Změním také svoji odpověď tak, aby v ní byl zohledněn váš komentář.
Odpověď
GNU Awk
#!/usr/bin/awk -fn @include "ord" BEGIN { RS = "%.." } { printf "%s", $0 if (RT != "") { printf "%s", chr("0x" substr(RT, 2)) } }
Odpověď
A další přístup Perlu:
#!/usr/bin/env perl use URI::Encode; my $uri = URI::Encode->new( { encode_reserved => 0 } ); while (<>) { print $uri->decode($_) }
Bude nutné nainstalovat modul URI::Encode
. V mém Debianu jsem mohl jednoduše spustit
sudo apt-get install liburi-encode-perl
Poté jsem spustil výše uvedený skript na testovací soubor obsahující:
http://foo%21asd%23asd%24%26asd%27asd%28asd%29
Výsledek byl (skript jsem uložil jako foo.pl
):
$ ./foo.pl http://foo!asd#asd$&asd"asd(asd)
Odpovědět
Odpověď ve (většinou Posix) prostředí:
$ input="%21%22" $ printf "`printf "%s\n" "$input" | sed -e "s/+/ /g" -e "s/%\(..\)/\\\\x\1/g"`" !"
Vysvětlení:
-
-e "s/+/ /g
transformuje každou+
ve vesmíru (jak je popsáno v normě url-encode) -
-e "s/%\(..\)/\\\\x\1/g"
transformujte každý%XX
v\\xXX
. Všimněte si, že jeden z\
bude odstraněn pomocí pravidel citování. - Vnitřní printf je právě tam, aby předal vstup sed. Můžeme jej nahradit jakýmkoli jiným mechanismem
- Vnější printf interpretuje
\\xXX
sekvence a zobrazuje výsledek.
Upravit:
Protože %
by měl být vždy interpretován v adresách URL, tuto odpověď je možné zjednodušit. Kromě toho si myslím, že je čistší použít xargs
místo backquotes (díky @josch).
$ input="%21%22+%25" $ printf "%s\n" "$input" | sed -e "s/+/ /g; s/%/\\x/g" | xargs -0 printf !" %
Bohužel (jak si všiml @josch) žádné z těchto řešení nevyhovuje Posixu, protože \x
úniková sekvence není v Posixu definována.
Komentáře
- Vítejte v U & L. Možná byste mohli vysvětlit tuto odpověď a její fungování. Obecně dáváme přednost tomu, aby naše odpovědi byly dlouhé, s podrobnostmi, nejen s úryvky kódu.
- Tato odpověď se mi opravdu líbí, protože je ‚ komplexní, přenosná a ‚ t vyžadují extra těžší externí programy jako perl nebo python. Funguje pro mě dobře.
- Skvělé řešení. A ještě kratší a chytřejší:
... | sed 's/+/ /g;s/%\(..\)/\\\\x\1/g'
. Možnost-e
zde lze ve skutečnosti vynechat … - @josch Máte pravdu,
printf
je integrovanýdash
a nerozpozná únik ‚\x
. Aby to fungovalo, můžete místoprintf
použít/usr/bin/printf
. Normálně byste měli být schopni použítcommand printf
, ale zdá se, že to nefunguje tak, jak by mělo. I nadále používá vestavěný. - @Jezz skutečně podpora pro
\x
únik není součástí POSIXu: pubs.opengroup.org / onlinepubs / 9699919799 / utilities / printf.html Během testů jsem viděl další problém. Možná budete chtít svůj..
regulární výraz nahradit[a-zA-Z0-9][a-zA-Z0-9]
, protože jinak zadejte jako ‚ %% % ‚ selže. Také jsem na konec přidals/%/%%/g
, abych se ujistil, že uniknou procenta pro printf.
Odpovědět
Jiné řešení využívající rubín (přijatá odpověď pythonu pro mě nefunguje)
alias urldecode="ruby -e "require \"cgi\"; puts CGI.unescape(ARGV[0])"" alias urlencode="ruby -e "require \"cgi\"; puts CGI.escape(ARGV[0])""
Příklad
$ urldecode "q+werty%3D%2F%3B" q werty=/; $ urlencode "q werty=/;" q+werty%3D%2F%3B
Komentáře
- Právě se používá rubín a tato tvrzení vypadají menší. Také jsem se změnil na ARGF.read, abych jej mohl propojit jako s mnoha dalšími nástroji!
Odpověď
Tady je funkce BASH, která umožňuje přesně toto:
function urldecode() { echo -ne $(echo -n "$1" | sed -E "s/%/\\\\x/g") }
Komentáře
- funguje jako kouzlo
- Pokud chcete převést
+
znaky na mezery a nevytvářet žádné procesy, můžete použít toto:: "${1//+/ }" && echo -e "${_//%/\\x}"
odpověď
Pouze prostředí:
$ x="a%20%25%e3%81%82";printf "${x//\%/\\x}" a %あ
Přidat --
nebo %b
zabráníte tomu, aby se s argumenty, které začínají pomlčkou, zacházelo jako s volbami.
V zsh ${x//%/a}
na konec přidá a
, ale ${x//\%/a}
nahradí %
a
.
Odpověď
Zde jsou relevantní bity z jiného skriptu (který jsem nestydatě) ukradl můj skript pro stahování youtube.com z jiné odpovědi) Napsal jsem dříve. Využívá sed
a shell k vytvoření funkčního urldecode.
set \! \" \# \$ \% \& \" \( \) \* \ \+ \, \/ \: \; \= \? \@ \[ \] for c do set "$@" ""$c" "$c"; shift; done curl -s "$url" | sed "s/\\u0026/\&/g;""$( printf "s/%%%X/\\%s/g;" "$@" )"
Nebudu přísahat, že je komplexní – a ve skutečnosti o tom pochybuji – ale určitě to zvládlo youtube.
Odpověď
Jednoduché řešení pro krátké řetězce (shell je pomalý):
$ str="q+werty%3D%2F%3B" $ a=${str//+/ };printf "$(echo "${a//%/\\x}")\n" q werty=/;