Як я можу кодувати і декодувати рядки, кодовані у відсотках, у командному рядку?


31

Як я можу кодувати і розшифровувати відсоткові (кодовані URL) рядки в командному рядку?

Я шукаю рішення, яке може зробити це:

$ percent-encode "ændrük"
%C3%A6ndr%C3%BCk
$ percent-decode "%C3%A6ndr%C3%BCk"
ændrük

Ви також хочете включити різні кодування? %E6ndr%FCkне схожий на мене (стандартний) UTF8. Або це просто приклад?
влаштовуйте

@arrange Дякую, що це зробив. Мабуть, я вибрав погане яблуко серед результатів пошуку для онлайн-конверторів.
ændrük

Імена файлів див. У розділі: Як видалити кодування URI у назвах файлів .
kenorb

Відповіді:


35

Ці команди виконують те, що ви хочете:

python -c "import urllib, sys; print urllib.quote(sys.argv[1])" æ
python -c "import urllib, sys; print urllib.unquote(sys.argv[1])" %C3%A6

Якщо ви хочете кодувати пробіли як +, замініть urllib.quoteна urllib.quote_plus.

Я здогадуюсь, ти захочеш їх псевдонімом ;-)


1
Що це за æ символ у кінці першого рядка? Редагувати: відповісти собі - зрозуміло, це лише один символьний рядок UTF8, який повинен бути закодований для прикладу :-)
TMG

1
як щодо python3?
Рікардо

@RicardoE перевіри цю відповідь .
Пабло А

27

оболонки

Спробуйте наступний командний рядок:

$ echo "%C3%A6ndr%C3%BCk" | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
ændrük

Ви можете визначити його псевдонімом і додати його до файлів rc оболонки :

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

Тоді кожен раз, коли вам це потрібно, просто перейдіть з:

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

баш

Під час написання сценарію ви можете використовувати такий синтаксис:

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

Однак вищевказаний синтаксис не буде +правильно обробляти плюси ( ), тому вам потрібно замінити їх пробілами через sed.

Ви також можете використовувати такі функції urlencode()та 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}"
}

Зауважте, що ваш urldecode () передбачає, що дані не містять зворотної косої риски.


bash + xxd

Функція Bash з 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
}

Знайдено у файлі суті cdown , також у stackoverflow .


Пітон

Спробуйте визначити такі псевдоніми:

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

Використання:

$ urlencode "ændrük"
C%26ndrC%3Ck
$ urldecode "%C3%A6ndr%C3%BCk"
ændrük

Джерело: русланспівак


PHP

За допомогою PHP можна спробувати наступну команду:

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

або просто:

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

Використовувати -Rдля введення декількох ліній


Perl

У Perl можна використовувати URI::Escape.

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

Або обробити файл:

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

sed

Використання sedможе бути досягнуто:

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

awk

Спробуйте Анон рішення:

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

Див.: Використання awk printf для urldecode тексту .


декодування імен файлів

Якщо вам потрібно видалити кодування URL з імен файлів, скористайтеся deurlnameінструментом renameutils(наприклад deurlname *.*).

Дивись також:


Пов'язані:


Версія bash + xxd не працює з рядками, які містять a %, можливо, ви могли б замінити printf "$c"їх printf "%c" "$c"? Інша проблема полягає в тому, що деякі діаграми, що не належать до ASCII, не кодуються (наприклад ä) у деяких мовних налаштуваннях, можливо, додають функцію a export LC_ALL=C(це не повинно впливати на щось поза функцією)?
12431234123412341234123

8

Процентне кодування зарезервованих символів URI та символів, що не належать до ASCII

jq -s -R -r @uri

-s( --slurp) читає вхідні рядки в масив і -s -R( --slurp --raw-input) зчитує введення в одну рядок. -r( --raw-output) виводить вміст рядків замість літеральних рядків JSON.

Процент-кодування всіх символів

xxd -p|tr -d \\n|sed 's/../%&/g'

tr -d \\nвидаляє канали ліній, які додаються xxd -pчерез кожні 60 символів.

Процентне кодування всіх символів, крім буквено-цифрових символів ASCII в Bash

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
}

Без -d ''цього можна було б пропустити стрічкові канали та нульові байти. Без IFS=цього було б замінити символи IFSз %00. Без LC_ALL=Cцього було б , наприклад , замінити з %3042в UTF-8 локалі.


5

Чистий розчин bash тільки для декодування :

$ a='%C3%A6ndr%C3%BCk'
$ echo -e "${a//%/\\x}"
ændrük

4

Я не можу коментувати найкращу відповідь у цій темі , тому ось моя.

Особисто я використовую ці псевдоніми для кодування та декодування 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])"'

Обидві команди дозволяють конвертувати дані, передані як аргумент командного рядка, або читати їх зі стандартного введення , тому що обидва однолінійки перевіряють, чи є аргументи командного рядка (навіть порожні) та обробляють їх або просто читають стандартне введення в іншому випадку.

оновлення 2015-07-16 (порожній 1-й аргумент)

... згідно з коментарем @muru.

оновлення 2017-05-28 (кодове косове зображення)

Якщо вам також потрібно кодувати косу рису, просто додайте порожній другий аргумент до функції цитування, тоді коса риса також буде закодована.

Отже, нарешті urlencode псевдонім у баші виглядає так:

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

1
Я думаю, що sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1]може бути більш доречним. Особливо, якщо ви використовуєте це в сценаріях і випадково даєте порожній перший аргумент.
муру

Відповідно до коментаря @muru, я змінив перевірку аргументу в командному рядку. Це було: len(sys.argv) < 2 and sys.stdin.read()[0:-1] or sys.argv[1] Тепер: sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1] Тобто, якщо є навіть порожній перший аргумент, команда не чекає введення зі стандартного вводу, а обробляє порожній аргумент.
DIG mbl

2

Я знайшов пакет, renameutilsщо містить утиліту, deurlnameяка здатна перейменовувати файл, що містить символи "відсотковим кодуванням".

На жаль, він не розшифровує stdin або параметр командного рядка, а лише перейменує файл, тому вам доведеться створити фіктивний файл, щоб отримати декодування (ім'я перейменованого файлу), але з деяким баш сценарієм процес може бути автоматизований. .

Немає інформації про частину кодування, навіть тому, що може бути сумнівним, які символи кодувати. Тільки не-ASCII?

Я думаю, що має бути якийсь кращий інструмент / метод.


1

Схожий на Stefano ansqer але в 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

Для кодування також косої риски:

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

Більше інформації про різницю тут .


0

Ось функція POSIX Awk для кодування:

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
}

Приклад

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.