URL kodlamasını çözme (yüzde kodlama)


100

URL kodlamasını çözmek istiyorum, bunu yapmak için herhangi bir yerleşik araç var mı veya bunu sedyapacak bir kod verebilecek biri var mı?

Unix.stackexchange.com ve internette biraz arama yaptım ama URL kodlamasını çözmek için herhangi bir komut satırı aracı bulamadım.

Yapmak istediğim şey sadece bir txtdosyayı düzenlemek.

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

Ve bunun gibi.


Yanıtlar:


107

Bu Python'u ne istersen yapan bir gömlek buldu:

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

Örnek

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

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

Referanslar


Bunu çok geç biliyorum, ama bunu yerinde düzenlemeyle yapabilmemin bir yolu var mı?
DisplayName

@DisplayName - Bana yeni bir Q gibi geliyor. Bunu sorar ve buna referans veririm.
slm

15
akış: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
Bunun bir Python 2 olduğunu unutmayın; pythonvarsayılan olarak 3 olan sistemlerde , bu hataya neden olur. Değişen pythoniçin python2yardımcı olur.
Ivan Kolmychek

4
İçin python3kullanabileceğiniz import urllib.parse as ulyerine import urllib as ul.
ibotty

61

sed

Aşağıdaki komut satırını deneyin:

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

veya aşağıdaki alternatifi kullanarak echo -e:

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

Not: Yukarıdaki sözdizimi +boşluklara dönüşmeyebilir ve tüm yeni satırları yiyebilir.


Bunu takma ad olarak tanımlayabilir ve kabuk rc dosyalarınıza ekleyebilirsiniz :

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

Sonra her ihtiyacın olduğunda, sadece git:

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

darbe

Komut dosyası yazarken aşağıdaki sözdizimini kullanabilirsiniz:

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

Ancak yukarıdaki sözdizimi pluses ( +) işlevini doğru işlemez , bu nedenle onları boşluklarla değiştirmelisiniz sed.

Aşağıdakileri urlencode()ve urldecode()işlevleri de kullanabilirsiniz :

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

Yukarıdaki urldecode()verilerin verilerin ters eğik çizgi içermediğini varsaydığını unutmayın .

Burada benzer Joel's sürüm bulduğu: https://github.com/sixarm/urldecode.sh


bash + xxd

xxdAracı ile Bash işlevi :

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
}

Bulundu cdown en özü dosyası ayrıca, stackoverflow .


PHP

PHP kullanarak aşağıdaki komutu deneyebilirsiniz:

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

ya da sadece:

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

-RÇoklu hat girişi için kullanın .


Perl

Perl'de kullanabilirsiniz URI::Escape.

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

Veya bir dosyayı işlemek için:

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

awk

Anon çözümünü deneyin :

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

Not: Parametre -nGNU'ya özgüdür awk.

Bakınız: Metnin kodunu değiştirmek için awk printf kullanımı .

dosya adlarını çözme

URL kodlamasını dosya adlarından kaldırmanız gerekirse deurlname, renameutils(örneğin deurlname *.*) aracını kullanın .

Ayrıca bakınız:


İlgili:


1
awk: Bu bir kütüphane işlevini kullandığından, chr()yalnızca GNU awk ( gawk) üzerinde çalışabilme olasılığı yüksektir . Ancak, bu durumda POSIX neredeyse hiç eşdeğer olacaktır awkçünkü -n(non-ondalık argümanları izin) seçeneğini IS bir GNU awközel.
sözdizimi

İlk sedkodunuz bana xargs: argument line too long162164 satırlık bir dosya veriyor .
Sparhawk

2
Buradaki çözümleriniz, URL’nin printf, bunun gibi kaçan yüzde işaretleri içerebileceğini dikkate almaz %25. Bunları printf için başka bir yüzde işareti ile basmadan kaçmadan printf'e geçirirsiniz %%.
josch

1
Bash sürümü local LC_ALL=Cen üstte gerektirir , aksi takdirde tüm geniş karakterler (Japonca, Çince, vb.) Baytlara uygun şekilde bölünmez.
Postost


18

Python standart kütüphanesinde bunun için yerleşik bir işlev vardır. Python 2'de öyle urllib.unquote.

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

Veya bir dosyayı işlemek için:

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

Python 3'te öyle urllib.parse.unquote.

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

Veya bir dosyayı işlemek için:

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

Perl'de kullanabilirsiniz URI::Escape.

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

Veya bir dosyayı işlemek için:

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

POSIX taşınabilir araçlarına bağlı kalmak istiyorsanız, bu çok garip çünkü tek ciddi aday onaltılık sayıları ayrıştırmayan awk. BusyBox dahil, yaygın awk uygulamalarına sahip örnekler için metni urldecode etmek için awk printf kullanma bölümüne bakın .


10

Basit fikirli bir sedkomut kullanmak istiyorsanız , aşağıdakileri kullanın:

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'

Ancak şöyle bir komut dosyası oluşturmak daha uygundur sedscript:

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

Sonra sed -f sedscript < old > newistediğiniz gibi çıkacak olan çalıştırın .


Kolaylıkla, komut urlencodedoğrudan kullanılabilir gridsite-clientspaketinden yüklenebilir (tarafından sudo apt-get install gridsite-clientsUbuntu / Debian sisteminde).

ADI

    urlencode - dizeleri URL kodlu biçime dönüştürür
ÖZET

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

AÇIKLAMA

    urlencode dizeleri RFC 1738'e göre kodlar.

    Başka bir deyişle, karakterler A- Z a- z 0- 9 . _ve -değiştirilmemişlerden geçirilir, ancak diğer tüm karakterler% HH olarak temsil edilir, burada HH iki basamaklı büyük harf onaltılık ASCII gösterimidir. Örneğin, URL http://www.gridpp.ac.uk/olurhttp%3A%2F%2Fwww.gridpp.ac.uk%2F

    urlencodeHer karakteri komut satırında verilen tüm dizelerde dönüştürür. Birden çok dize verilirse, dönüştürme işleminden önce boşluk bırakarak birleştirilirler.

SEÇENEKLER
    -m
      Tam dönüşüm yerine, GridSite "az URL 0-9" olan hafif URL kodlaması yapar. = - _ @ ve / değiştirilmemiş olarak geçirilir. Bu, biraz daha okunabilir insan dizileriyle sonuçlanır, ancak uygulama herhangi bir eğik çizginin gösterdiği dizinleri oluşturmak veya simüle etmek için hazırlanmalıdır.
    -d
      RFC 1738'e göre kodlama yerine URL kod çözme işlemi yapın.% HH ve% hh dizeleri dönüştürülür ve diğer karakterler +uzaya dönüştürülen istisna dışında değiştirilmemiş şekilde geçirilir .

Kod çözme URL'si örneği:

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

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


4
Bu kötü bir çözüm, çünkü her karaktere kodlama gerektiriyor. Bu problem, sıklıkla kullanılan %20kaçış sırasını eksik kodunuzla örneklenmiştir .
Aşırı

@Overv Ben sadece revize ettik
Pandya

Ayrıca, ne yaptığını tekrar kontrol etmek isteyebilirsiniz s/%26/&/g. (
G-Man

9

Perl bir liner:

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

Örnek:

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

1
Perl modülleri kurmakla uğraşmak istemiyorsanız, bu cevap çekicidir.
Sridhar Sarnobat,

1
MacOS'ta benim için zarif bir şekilde çalışan tek kişi.
Qix


7

Bu konudaki en iyi cevap hakkında yorum yapamam , bu yüzden işte benim.

Şahsen bu takma adları URL kodlama ve kod çözme için kullanırım:

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

Her iki komut da verileri dönüştürmenize, komut satırı argümanı olarak geçirmenize veya standart girdiden okumanıza olanak tanır , çünkü her iki tek gömlek komut satırı argümanları olup olmadığını kontrol eder (hatta boş olanları) ve bunları işler veya yalnızca standart girişi okur.


2017-05-23 güncellemesi (eğik çizgi kodlaması)

@ Bevor'un yorumuna cevap olarak.

Eğer eğik çizgiyi de kodlamanız gerekiyorsa, sadece teklif fonksiyonuna boş bir ikinci argüman ekleyin, o zaman eğik çizgi de kodlanacaktır.

Yani, son olarak urlencode takma içinde bash şuna benzer:

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

Örnek

$ 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
Eğik çizgileri kodlamaz.
Bevor

@Bevor: Örnek?
DIG mbl

Urlencode "Проба пера" -> sonucuna eğik çizgi ekleyin: Eğik çizgi kodlanmadı.
Bevor

1
@Bevor: Haklısın. Yorumun için teşekkür ederim. Ayrıca cevabınızı yorumunuzu yansıtacak şekilde değiştireceğim.
DIG mbl

4

Ve başka bir Perl yaklaşımı:

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

    print $uri->decode($_)
}

URI::EncodeModülü kurmanız gerekecek . Debian'ımda basitçe koşabilirim

sudo apt-get install liburi-encode-perl

Sonra yukarıdaki betiği içeren bir test dosyasına koştum:

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

Sonuç (betiği farklı kaydetmiştim foo.pl):

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

3

(Çoğunlukla Posix) kabuğundaki bir cevap:

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

Açıklama:

  • -e 's/+/ /gher birini +uzayda dönüştürür (url kodlama normunda tanımlandığı gibi)
  • -e 's/%\(..\)/\\\\x\1/g'Her bir dönüşüm %XXde \\xXX. \Kurallardan birinin alıntılardan birinin kaldırılacağına dikkat edin .
  • İçteki printf, girişi baştan sona geçirmek için oradadır. Başka bir mekanizma ile değiştirebiliriz
  • Dış baskı \\xXXdizileri ve görüntüleme sonucunu yorumlar.

Düzenle:

Beri %hep URL'lerindeki yorumlanmıştır gerektiğini, cevabı basitleştirmek mümkündür. Ek olarak xargs, geri tırnak yerine kullanmak daha temiz olduğunu düşünüyorum (@josch sayesinde).

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

Ne yazık ki, (@josch'un farkettiği gibi) bu çözümlerin hiçbiri Posix uyumlu \xdeğildir, çünkü kaçış dizisi Posix'te tanımlanmamıştır.


U&L'ye hoş geldiniz. Belki bu cevabı ve nasıl çalıştığını açıklayabilirsiniz. Genelde cevaplarımızın sadece kod snippet'leri değil ayrıntılarla uzun biçim olmasını tercih ediyoruz.
slm

Bu cevabı çok beğendim çünkü kapsamlı, taşınabilir ve perl veya python gibi ekstra ağır harici programlar gerektirmiyor. Benim için iyi çalışıyor.
Steve Will

1
Harika bir çözüm. Ve hatta daha kısa ve daha akıllı: ... | sed 's/+/ /g;s/%\(..\)/\\\\x\1/g'. -eSeçenek ... Burada aslında atlanabilir
SyntaxError

1
@josch Haklısın printf, bir yerleşik dashve \xkaçmayı tanımıyor . Çalışması için /usr/bin/printfyerine kullanabilirsiniz printf. Normalde, kullanabilmelisiniz command printf, ancak olması gerektiği gibi çalışmıyor gibi görünüyor. Yerleşik kullanmaya devam ediyor.
Jérôme Pouiller

1
@Jezz gerçekten \xkaçış için destek POSIX'in bir parçası değil: pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html Testlerim sırasında başka bir sorun gördüm. Eğer değiştirmek isteyebilirsiniz ..tarafından regex [a-zA-Z0-9][a-zA-Z0-9]aksi '%%%' gibi girdi başarısız olur çünkü. Ayrıca s/%/%%/gprintf için yüzde kaçmak emin olmak için sonunda ekledi .
josch

1

Kabuk okunur:

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

Ekle --veya %bseçenekler olarak tedavi altına gelen bir çizgi ile başlayan argümanlar önlemek için.

Zsh olarak ${x//%/a}ekler asonuna ancak ${x//\%/a}yerini %ile a.


1

İşte daha önce yazdığım başka bir betiğin ilgili bitleri (sadece youtube.com indirme betiğimden utanmadan çaldığım ) . sedÇalışan bir urldecode oluşturmak için ve kabuk kullanır .

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

Yemin ederim kapsamlı - ve aslında şüpheliyim - ama youtube'u yeterince idare etti.


1

İşte tam olarak bunu yapmak için bir BASH işlevidir:

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

çekicilik gibi çalışır
Abdelraouf Sabri

0

Yakut kullanan başka bir çözüm (kabul edilen python cevabı benim için işe yaramadı)

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

Örnek

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

$ urlencode 'q werty=/;'
q+werty%3D%2F%3B
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.