Как я могу кодировать и декодировать кодированные в процентах строки в командной строке?


31

Как я могу кодировать и декодировать строки в процентах (URL-кодирование) в командной строке?

Я ищу решение, которое может сделать это:

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

Вы тоже хотите включить разные кодировки? %E6ndr%FCkмне не кажется (стандартным) UTF8. Или это просто пример?
договориться

@arrange Спасибо, что поймали это. Видимо, я выбрал плохое яблоко среди результатов поиска для онлайн-конвертеров.
rndrük

Ответы:


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

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

Однако приведенный выше синтаксис не будет +правильно обрабатывать pluses ( ), поэтому вы должны заменить их пробелами через 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 () предполагает, что данные не содержат обратной косой черты.


Баш + 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
}

Находится в gist-файле 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может быть достигнуто путем:

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 *.*).

Смотрите также:


Связанный:


Баш + XXD версия не работает со строками , которые содержат %, может быть , вы могли бы заменить printf "$c"с printf "%c" "$c"? Другая проблема заключается в том, что некоторые не-ASCII-символы не закодированы (например, äв некоторых языковых настройках), может быть, добавить 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

Pure Bash Solution только для декодирования :

$ 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 псевдоним в bash выглядит так:

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которая может переименовывать файл, содержащий символы в процентах.

К сожалению, он не декодирует стандартный ввод или параметр командной строки, а только переименовывает файл, поэтому для получения декодирования (имени переименованного файла) необходимо создать фиктивный файл, но с помощью некоторых сценариев bash процесс можно автоматизировать. ,

Нет информации о кодирующей части, даже потому что может быть сомнительно, какие символы кодировать. Только не ASCII?

Я думаю, что должен быть какой-то лучший инструмент / метод.


1

Аналогично ответу Стефано, но в 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.