Bagaimana saya bisa menyandikan dan mendekodekan string persen-disandikan (URL disandikan) pada baris perintah?
Saya mencari solusi yang dapat melakukan ini:
$ percent-encode "ændrük"
%C3%A6ndr%C3%BCk
$ percent-decode "%C3%A6ndr%C3%BCk"
ændrük
Bagaimana saya bisa menyandikan dan mendekodekan string persen-disandikan (URL disandikan) pada baris perintah?
Saya mencari solusi yang dapat melakukan ini:
$ percent-encode "ændrük"
%C3%A6ndr%C3%BCk
$ percent-decode "%C3%A6ndr%C3%BCk"
ændrük
Jawaban:
Perintah-perintah ini melakukan apa yang Anda inginkan:
python -c "import urllib, sys; print urllib.quote(sys.argv[1])" æ
python -c "import urllib, sys; print urllib.unquote(sys.argv[1])" %C3%A6
Jika Anda ingin menyandikan spasi sebagai +
, ganti urllib.quote
dengan urllib.quote_plus
.
Saya kira Anda akan ingin alias mereka ;-)
Coba baris perintah berikut:
$ echo "%C3%A6ndr%C3%BCk" | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
ændrük
Anda dapat mendefinisikannya sebagai alias dan menambahkannya ke file rc shell Anda :
$ alias urldecode='sed "s@+@ @g;s@%@\\\\x@g" | xargs -0 printf "%b"'
Lalu setiap kali Anda membutuhkannya, cukup ikuti:
$ echo "http%3A%2F%2Fwww" | urldecode
http://www
Saat membuat skrip, Anda dapat menggunakan sintaks berikut:
input="http%3A%2F%2Fwww"
decoded=$(printf '%b' "${input//%/\\x}")
Namun sintaks di atas tidak akan menangani plus ( +
) dengan benar, jadi Anda harus menggantinya dengan spasi via sed
.
Anda juga dapat menggunakan yang berikut ini urlencode()
dan urldecode()
fungsinya:
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}"
}
Perhatikan bahwa kode ur Anda () menganggap data tidak mengandung garis miring terbalik.
Fungsi Bash dengan xxd
alat:
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
}
Ditemukan di file inti cdown , juga di stackoverflow .
Cobalah untuk menentukan alias berikut:
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])"'
Pemakaian:
$ urlencode "ændrük"
C%26ndrC%3Ck
$ urldecode "%C3%A6ndr%C3%BCk"
ændrük
Sumber: ruslanspivak
Menggunakan PHP Anda dapat mencoba perintah berikut:
$ echo oil+and+gas | php -r 'echo urldecode(fgets(STDIN));' // Or: php://stdin
oil and gas
atau hanya:
php -r 'echo urldecode("oil+and+gas");'
Gunakan -R
untuk input baris ganda.
Di Perl Anda dapat menggunakan URI::Escape
.
decoded_url=$(perl -MURI::Escape -e 'print uri_unescape($ARGV[0])' "$encoded_url")
Atau untuk memproses file:
perl -i -MURI::Escape -e 'print uri_unescape($ARGV[0])' file
Penggunaan sed
dapat dicapai dengan:
cat file | sed -e's/%\([0-9A-F][0-9A-F]\)/\\\\\x\1/g' | xargs echo -e
Coba solusi anon :
awk -niord '{printf RT?$0chr("0x"substr(RT,2)):$0}' RS=%..
Lihat: Menggunakan awk printf untuk urldecode teks .
Jika Anda perlu menghapus penyandian url dari nama file, gunakan deurlname
alat dari renameutils
(mis deurlname *.*
.).
Lihat juga:
Terkait:
%
, mungkin Anda bisa menggantinya printf "$c"
dengan printf "%c" "$c"
? Masalah lain adalah bahwa beberapa karakter non-ASCII tidak dikodekan (seperti ä
) dalam beberapa pengaturan bahasa, mungkin menambahkan export LC_ALL=C
fungsi a (yang seharusnya tidak mempengaruhi apa pun di luar fungsi)?
jq -s -R -r @uri
-s
( --slurp
) membaca baris input ke dalam array dan -s -R
( --slurp --raw-input
) membaca input ke dalam satu string. -r
( --raw-output
) menampilkan isi string bukannya string literal JSON.
xxd -p|tr -d \\n|sed 's/../%&/g'
tr -d \\n
menghapus umpan baris yang ditambahkan xxd -p
setelah setiap 60 karakter.
eu () {
local LC_ALL=C c
while IFS= read -r -n1 -d '' c
do
if [[ $c = [[:alnum:]] ]]
then
printf %s "$c"
else
printf %%%02x "'$c"
fi
done
}
Tanpa -d ''
ini akan melewatkan baris baris dan byte nol. Tanpa IFS=
ini akan menggantikan karakter IFS
dengan %00
. Tanpa LC_ALL=C
ini misalnya akan diganti あ
dengan %3042
di lokal UTF-8.
Saya tidak dapat mengomentari jawaban terbaik di utas ini , jadi inilah milik saya.
Secara pribadi, saya menggunakan alias ini untuk penyandian dan penguraian 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])"'
Kedua perintah memungkinkan Anda untuk mengkonversi data, diteruskan sebagai argumen baris perintah atau membacanya dari input standar , karena keduanya satu-baris memeriksa apakah ada argumen baris perintah (bahkan yang kosong) dan memprosesnya atau hanya membaca input standar jika tidak.
... menurut komentar @muru.
Jika Anda juga perlu menyandikan slash, cukup tambahkan argumen kosong kedua ke fungsi kutipan, maka slash juga akan dikodekan.
Jadi, akhirnya urlencode
alias dalam bash terlihat seperti ini:
alias urlencode='python -c "import urllib, sys; print urllib.quote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1], \"\")"'
$ 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
sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1]
mungkin lebih tepat. Terutama jika Anda menggunakan ini dalam skrip dan tanpa sengaja memberikan argumen kosong pertama.
len(sys.argv) < 2 and sys.stdin.read()[0:-1] or sys.argv[1]
Sekarang: sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1]
Yaitu, jika bahkan ada argumen pertama yang kosong, perintah tidak menunggu input dari input standar, tetapi memproses argumen kosong.
Saya menemukan sebuah paket,, renameutils
yang berisi utilitas deurlname
yang dapat mengubah nama file yang berisi karakter "persen-disandikan".
Sayangnya, ini tidak men-decode stdin atau opsi baris perintah, tetapi hanya mengganti nama file, jadi Anda harus membuat file dummy untuk mendapatkan decoding (nama file yang diganti nama), tetapi dengan beberapa bash scripting prosesnya dapat otomatis .
Tidak ada informasi tentang bagian penyandian, bahkan karena bisa dipertanyakan karakter mana yang disandikan. Hanya non-ASCII?
Saya pikir harus ada beberapa alat / metode yang lebih baik.
Mirip dengan Stefano ansqer tetapi dengan Python 3:
python -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))" æ
python -c "import urllib.parse, sys; print(urllib.parse.unquote(sys.argv[1]))" %C3%A6
Untuk menyandikan juga garis miring:
python -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1], \"\"))"
Info lebih lanjut tentang perbedaannya di sini .
Berikut adalah fungsi POSIX Awk untuk penyandian:
function encodeURIComponent(str, j, q) {
while (y++ < 125) z[sprintf("%c", y)] = y
while (y = substr(str, ++j, 1))
q = y ~ /[[:alnum:]_.!~*\47()-]/ ? q y : q sprintf("%%%02X", z[y])
return q
}
%E6ndr%FCk
tidak terlihat seperti (standar) UTF8 bagi saya. Atau hanya sebuah contoh?