Como posso codificar e decodificar strings codificadas por porcentagem na linha de comando?

29

Como posso codificar e decodificar strings codificadas por percentual (codificadas por URL) na linha de comando?

Estou procurando uma solução que possa fazer isso:

$ percent-encode "ændrük"
%C3%A6ndr%C3%BCk
$ percent-decode "%C3%A6ndr%C3%BCk"
ændrük
    
por ændrük 19.07.2011 / 22:23

7 respostas

33

Estes comandos fazem o que você quer:

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

Se você deseja codificar espaços como + , substitua urllib.quote por urllib.quote_plus .

Eu estou supondo que você vai querer apelidá-los ;-)

    
por Stefano Palazzo 19.07.2011 / 23:22
26

shell

Experimente a seguinte linha de comando:

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

Você pode defini-lo como alias e adicioná-lo ao seu arquivo rc :

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

Então, toda vez que precisar, basta ir com:

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

bash

Ao criar scripts, você pode usar a seguinte sintaxe:

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

No entanto, a sintaxe acima não processa os prós e contras ( + ) corretamente, então você precisa substituí-los por espaços com sed .

Você também pode usar as seguintes funções urlencode() e 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}"
}

Note that your urldecode() assumes the data contains no backslash.

bash + xxd

Função de bash com a ferramenta 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
}

Encontrado no arquivo gist do cdown , também em stackoverflow .

Python

Tente definir os seguintes alias:

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

Uso:

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

Fonte: ruslanspivak

PHP

Usando o PHP, você pode tentar o seguinte comando:

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

ou apenas:

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

Use -R para várias entradas de linha.

Perl

Em Perl, você pode usar URI::Escape .

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

Ou para processar um arquivo:

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

sed

Usar sed pode ser obtido por:

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

awk

Tente a solução anon :

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

Veja: Usando awk printf para urldecode text .

decodificando nomes de arquivos

Se você precisar remover a codificação de URL dos nomes dos arquivos, use a ferramenta deurlname de renameutils (por exemplo, deurlname *.* ).

Veja também:

Relacionados:

por kenorb 14.05.2013 / 15:06
8

Codificar por percentual os caracteres URI reservados e caracteres não ASCII

jq -s -R -r @uri

-s ( --slurp ) lê linhas de entrada em uma matriz e -s -R ( --slurp --raw-input ) lê a entrada em uma única cadeia. -r ( --raw-output ) gera o conteúdo de strings em vez de literais de string JSON.

Codifique em porcentagem todos os caracteres

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

tr -d \n remove os feeds de linha adicionados por xxd -p após cada 60 caracteres.

Codifica em porcentagem todos os caracteres, exceto caracteres alfanuméricos ASCII no 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
}

Sem -d '' , isso ignoraria os feeds de linha e os bytes nulos. Sem IFS= , isso substituiria os caracteres em IFS por %00 . Sem LC_ALL=C , por exemplo, substituiria por %3042 em um código do idioma UTF-8.

    
por user4669748 22.12.2015 / 03:26
5

Solução bash pura para decodificação apenas :

$ a='%C3%A6ndr%C3%BCk'
$ echo -e "${a//%/\x}"
ændrük
    
por loentar 09.10.2014 / 21:46
4

Não posso comentar a melhor resposta neste tópico , então aqui está a minha.

Pessoalmente, eu uso esses aliases para codificação e decodificação de 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])"'

Ambos os comandos permitem converter dados, passados como um argumento de linha de comando ou lê-los a partir de entrada padrão , porque ambos os marcadores verificam se há argumentos de linha de comando (mesmo os vazios) e processá-los ou apenas ler a entrada padrão de outra forma.

atualizar 2015-07-16 (vazio 1º argumento)

... de acordo com o comentário @muru.

atualizar 2017-05-28 (codificação de barra)

Se você também precisar codificar a barra, basta adicionar um segundo argumento vazio à função quote e, em seguida, a barra também será codificada.

Então, finalmente, urlencode alias em bash tem esta aparência:

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

Exemplo

$ 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
    
por DIG mbl 16.07.2015 / 01:47
3

Eu encontrei um pacote, renameutils , que contém o utilitário deurlname que é capaz de renomear um arquivo contendo caracteres "percentuais".

Infelizmente, ele não decodifica stdin ou uma opção de linha de comando, mas apenas renomeia um arquivo, então você tem que criar um arquivo fictício para obter a decodificação (o nome do arquivo renomeado), mas com algum script bash do processo pode ser automatizado.

Nenhuma informação sobre a parte de codificação, mesmo porque pode ser questionável quais caracteres codificar. Apenas não ASCII?

Acho que deveria haver alguma ferramenta / método melhor.

    
por enzotib 19.07.2011 / 23:15
0

Aqui está uma função POSIX Awk para codificação:

function encodeURIComponent(str, j, q) {
  while (y++ < 125) z[sprintf("%c", y)] = y
  while (y = substr(str, ++j, 1))
    q = y ~ /[[:alnum:]_.!~*()-]/ ? q y : q sprintf("%%%02X", z[y])
  return q
}

Exemplo

    
por Steven Penny 29.02.2016 / 02:42