Comment puis-je encoder et décoder des chaînes encodées en pourcentage sur la ligne de commande?

31

Comment puis-je encoder et décoder des chaînes encodées en pourcentage (encodées URL) sur la ligne de commande?

Je recherche une solution qui peut le faire:

$ percent-encode "ændrük"
%C3%A6ndr%C3%BCk
$ percent-decode "%C3%A6ndr%C3%BCk"
ændrük
ændrük
la source
Voulez-vous également incorporer différents encodages? %E6ndr%FCkne me ressemble pas (standard) UTF8. Ou c'est juste un exemple?
arranger le
@arrange Merci d'avoir attrapé ça. Apparemment, j'ai choisi la mauvaise pomme parmi les résultats de recherche pour les convertisseurs en ligne.
ændrük
Pour les noms de fichiers, voir: Comment supprimer le codage URI dans les noms de fichiers .
kenorb

Réponses:

35

Ces commandes font ce que vous voulez:

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 vous souhaitez encoder des espaces en tant que +, remplacez urllib.quotepar urllib.quote_plus.

Je suppose que vous voudrez les alias ;-)

Stefano Palazzo
la source
1
Quel est ce caractère æ à la fin de la première ligne? Edit: répondre à moi-même - j'ai compris, c'est juste une chaîne de caractères UTF8 à coder à titre d'exemple :-)
TMG
1
que diriez-vous de python3?
RicardoE
@RicardoE vérifier cette réponse .
Pablo A
27

coquille

Essayez la ligne de commande suivante:

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

Vous pouvez le définir comme alias et l'ajouter à vos fichiers shell rc :

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

Ensuite, chaque fois que vous en avez besoin, optez simplement pour:

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

frapper

Lors de l'écriture de scripts, vous pouvez utiliser la syntaxe suivante:

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

Cependant, la syntaxe ci-dessus ne gérera pas pluses ( +) correctement, vous devez donc les remplacer par des espaces via sed.

Vous pouvez également utiliser les éléments suivants urlencode()et urldecode()fonctions:

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

Notez que votre urldecode () suppose que les données ne contiennent pas de barre oblique inverse.


bash + xxd

Fonction Bash avec xxdoutil:

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
}

Trouvé dans le fichier gist de cdown , également sur stackoverflow .


Python

Essayez de définir les alias suivants:

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

Usage:

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

Source: ruslanspivak


PHP

En utilisant PHP, vous pouvez essayer la commande suivante:

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

ou juste:

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

À utiliser -Rpour l'entrée de plusieurs lignes.


Perl

En Perl, vous pouvez utiliser URI::Escape.

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

Ou pour traiter un fichier:

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

sed

L'utilisation sedpeut être réalisée par:

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

awk

Essayez une solution unique :

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

Voir: Utiliser awk printf pour urldecode .


décodage des noms de fichiers

Si vous devez supprimer le codage url des noms de fichiers, utilisez l' deurlnameoutil de renameutils(par exemple deurlname *.*).

Voir également:


En relation:

Kenorb
la source
La version bash + xxd ne fonctionne pas avec les chaînes qui contiennent un %, peut-être pourriez-vous remplacer printf "$c"par printf "%c" "$c"? Un autre problème est que certains caractères non ASCII ne sont pas encodés (comme ä) dans certains paramètres de langue, peut-être ajouter un export LC_ALL=Cdans la fonction (cela ne devrait pas affecter quoi que ce soit en dehors de la fonction)?
12431234123412341234123
8

Codage en pourcentage caractères URI réservés et caractères non ASCII

jq -s -R -r @uri

-s( --slurp) lit les lignes d'entrée dans un tableau et -s -R( --slurp --raw-input) lit l'entrée dans une seule chaîne. -r(--raw-output ) affiche le contenu des chaînes au lieu des littéraux de chaîne JSON.

Encoder en pourcentage tous les caractères

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

tr -d \\nsupprime les sauts de ligne qui sont ajoutés par xxd -ptous les 60 caractères.

Encoder en pourcentage tous les caractères sauf les caractères alphanumériques ASCII dans 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
}

Sans -d ''cela, les sauts de ligne et les octets nuls seraient ignorés. Sans IFS=cela, les caractères seraient remplacés IFSpar %00. Sans LC_ALL=Ccela, par exemple, le remplacerait par %3042un environnement local UTF-8.

nisetama
la source
5

Solution de bash pure pour le décodage uniquement :

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

Je ne peux pas commenter la meilleure réponse dans ce fil , alors voici la mienne.

Personnellement, j'utilise ces alias pour l'encodage et le décodage d'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])"'

Les deux commandes vous permettent de convertir des données, passées en argument de ligne de commande ou de les lire à partir de l'entrée standard , car les deux lignes simples vérifient s'il existe des arguments de ligne de commande (même vides) et les traitent ou lisent simplement l'entrée standard autrement.

mise à jour 2015-07-16 (1er argument vide)

... selon le commentaire de @muru.

mise à jour 2017-05-28 (codage slash)

Si vous devez également coder la barre oblique, ajoutez simplement un deuxième argument vide à la fonction de devis, puis la barre oblique sera également codée.

Donc, finalement, l' urlencode alias dans bash ressemble à ceci:

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

Exemple

$ 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
la source
1
Je pense que cela sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1]pourrait être plus approprié. Surtout si vous l'utilisez dans des scripts et donnez accidentellement un premier argument vide.
muru
Selon le commentaire de @muru, j'ai changé la vérification d'un argument sur la ligne de commande. C'était: len(sys.argv) < 2 and sys.stdin.read()[0:-1] or sys.argv[1] Maintenant: sys.argv[1] if len(sys.argv) > 1 else sys.stdin.read()[0:-1] c'est-à-dire, s'il y a même un premier argument vide, la commande n'attend pas l'entrée de l'entrée standard, mais traite un argument vide.
DIG mbl
2

J'ai trouvé un package,, renameutilsqui contient l'utilitaire deurlnamecapable de renommer un fichier contenant des caractères "encodés en pourcentage".

Malheureusement, il ne décode pas stdin ou une option de ligne de commande, mais renomme uniquement un fichier, vous devez donc créer un fichier factice pour obtenir le décodage (le nom du fichier renommé), mais avec certains scripts bash, le processus peut être automatisé .

Aucune information sur la partie encodage, même parce qu'il pourrait être question des caractères à encoder. Uniquement non ASCII?

Je pense qu'il devrait y avoir un meilleur outil / méthode.

enzotib
la source
1

Similaire à Stefano ansqer mais 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

Pour coder également des barres obliques:

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

Plus d'informations sur la différence ici .

Pablo A
la source
0

Voici une fonction POSIX Awk pour l'encodage:

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
}

Exemple

Steven Penny
la source