¿Cómo puedo codificar y decodificar cadenas codificadas en porcentaje en la línea de comando?

31

¿Cómo puedo codificar y decodificar cadenas codificadas por porcentaje (codificadas por URL) en la línea de comandos?

Estoy buscando una solución que pueda hacer esto:

$ percent-encode "ændrük"
%C3%A6ndr%C3%BCk
$ percent-decode "%C3%A6ndr%C3%BCk"
ændrük
ændrük
fuente
¿Quieres incorporar diferentes codificaciones también? %E6ndr%FCkno me parece UTF8 (estándar). ¿O es solo un ejemplo?
organizar el
@arrange Gracias por atrapar eso. Aparentemente elegí la manzana podrida entre los resultados de búsqueda para convertidores en línea.
ændrük
Para los nombres de archivo, consulte: Cómo eliminar la codificación URI en los nombres de archivo .
kenorb

Respuestas:

35

Estos comandos hacen lo que quieres:

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

Si desea codificar espacios como +, reemplácelos urllib.quotecon urllib.quote_plus.

Supongo que querrás ponerles alias ;-)

Stefano Palazzo
fuente
1
¿Cuál es ese æ personaje al final de la primera línea? Editar: respondiéndome a mí mismo: lo tengo, es solo una cadena UTF8 de un solo carácter para codificar, por ejemplo, propósito :-)
TMG
1
¿Qué tal python3?
RicardoE
@RicardoE verifica esta respuesta .
Pablo A
27

cáscara

Pruebe la siguiente línea de comando:

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

Puede definirlo como alias y agregarlo a sus archivos rc de shell :

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

Luego, cada vez que lo necesite, simplemente vaya con:

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

golpetazo

Al crear secuencias de comandos, puede usar la siguiente sintaxis:

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

Sin embargo, la sintaxis anterior no manejará más ( +) correctamente, por lo que debe reemplazarlos con espacios a través de sed.

También puede usar lo siguiente urlencode()y las urldecode()funciones:

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

Tenga en cuenta que su urldecode () supone que los datos no contienen barra invertida.


bash + xxd

Función bash con xxdherramienta:

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
}

Se encuentra en el archivo GIST de Cdown , también en stackoverflow .


Pitón

Intente definir los siguientes 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

Fuente: ruslanspivak


PHP

Usando PHP puedes probar el siguiente comando:

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

o solo:

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

Úselo -Rpara entrada de línea múltiple.


Perl

En Perl puedes usar URI::Escape.

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

O para procesar un archivo:

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

sed

El uso sedse puede lograr mediante:

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

awk

Trate anon solución:

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

Consulte: Uso de awk printf para codificar el texto .


decodificar nombres de archivo

Si necesita eliminar la codificación de URL de los nombres de archivo, use la deurlnameherramienta de renameutils(p deurlname *.*. Ej .).

Ver también:


Relacionado:

kenorb
fuente
La versión + xxd fiesta no funciona con cadenas que contienen una %, tal vez se podría reemplazar printf "$c"con printf "%c" "$c"? Otro problema es que algunos caracteres no ASCII no están codificados (como ä) en algunas configuraciones de idioma, ¿tal vez agregar un export LC_ALL=Cen la función (que no debería afectar a nada fuera de la función)?
12431234123412341234123
8

Codifique el porcentaje de caracteres URI reservados y caracteres no ASCII

jq -s -R -r @uri

-s( --slurp) lee líneas de entrada en una matriz y-s -R ( --slurp --raw-input) lee la entrada en una sola cadena. -r( --raw-output) genera el contenido de cadenas en lugar de literales de cadena JSON.

Codificación porcentual de todos los caracteres

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

tr -d \\nelimina los avances de línea que se agregan xxd -pdespués de cada 60 caracteres.

Codificación porcentual de todos los caracteres, excepto los caracteres alfanuméricos ASCII en 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
}

Sin -d ''esto, se omitirían los avances de línea y los bytes nulos. Sin IFS=esto reemplazaría los caracteres IFScon %00. Sin LC_ALL=Cesto, por ejemplo, reemplazaría con %3042en un entorno local UTF-8.

nisetama
fuente
5

Solución de bash pura solo para decodificar :

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

No puedo comentar sobre la mejor respuesta en este hilo , así que aquí está el mío.

Personalmente, uso estos alias para la codificación y decodificación 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 comandos le permiten convertir datos, pasados ​​como un argumento de línea de comandos o leerlos desde una entrada estándar , porque ambos de una línea verifican si hay argumentos de línea de comandos (incluso vacíos) y los procesan o simplemente leen la entrada estándar de lo contrario.

actualizar 2015-07-16 (vacío 1er argumento)

... según el comentario de @muru.

actualizar 2017-05-28 (codificación de barra)

Si también necesita codificar la barra diagonal, simplemente agregue un segundo argumento vacío a la función de comillas, entonces la barra también se codificará.

Entonces, finalmente el urlencode alias en bash se ve así:

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

Ejemplo

$ 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
DIG mbl
fuente
1
Creo que sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1]podría ser más apropiado. Especialmente si usa esto en scripts y accidentalmente da un primer argumento vacío.
muru
Según el comentario de @muru, cambié la comprobación de un argumento en la línea de comando. Era: len(sys.argv) < 2 and sys.stdin.read()[0:-1] or sys.argv[1] Ahora: sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1] es decir, si incluso hay un primer argumento vacío, el comando no espera la entrada de la entrada estándar, sino que procesa un argumento vacío.
DIG mbl
2

Encontré un paquete renameutilsque contiene la utilidad deurlnameque puede cambiar el nombre de un archivo que contiene caracteres "codificados en porcentaje".

Desafortunadamente, no decodifica stdin o una opción de línea de comando, solo cambia el nombre de un archivo, por lo que debe crear un archivo ficticio para obtener la decodificación (el nombre del archivo renombrado), pero con algunas secuencias de comandos bash, el proceso puede automatizarse .

No hay información sobre la parte de codificación, incluso porque podría ser cuestionable qué caracteres codificar. Sólo no ASCII?

Creo que debería haber alguna herramienta / método mejor.

enzotib
fuente
1

Similar a Stefano ansqer pero en 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

Para codificar también barras:

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

Más información sobre la diferencia aquí .

Pablo A
fuente
0

Aquí hay una función POSIX Awk para codificar:

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
}

Ejemplo

Steven Penny
fuente