Comment décoder URL-chaîne codée en shell?
J'ai un fichier avec une liste des user-agents qui sont codés.
E. g.:
Mozilla%2F5.0%20%28Macintosh%3B%20U%3B%20Intel%20Mac%20OS%20X%2010.6%3B%20en
Je veux un script shell qui peut lire ce fichier et écrire dans un nouveau fichier avec chaînes décodées.
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en
J'ai essayé d'utiliser cet exemple pour obtenir ce que ça va, mais il n'est pas jusque-là.
$ echo -e "$(echo "%31+%32%0A%33+%34" | sed 'y/+//; s/%/\\x/g')"
Mon script ressemble:
#!/bin/bash
for f in *.log; do
echo -e "$(cat $f | sed 'y/+//; s/%/\x/g')" > y.log
done
- ligne 5: "x" devrait être le double échappement (
s/%/\x/g
->s/%/\\x/g
- Merci pour le pointeur. Essayez d'échappement double. Ne sais pas comment je l'ai raté quand j'ai copié à partir de quelque part d'autre. Sera mise à jour.
- unix.stackexchange.com/questions/159253/...
Vous devez vous connecter pour publier un commentaire.
Voici un exemple simple d'une solution en ligne.
Il peut ressembler à perl 🙂 mais c'est juste pure bash. Pas de awks, pas de sed ... pas de frais généraux. À l'aide de l' : builtin, les paramètres spéciaux, modèle de substitution et l'écho builtin l'option-e pour traduire les codes hex en personnages. Voir le bash de la page de manuel pour plus de détails. Vous pouvez utiliser cette fonction en tant que distincte de commande
ou dans les affectations de variables, comme suit:
+
avec l'espace et le${_//%/\\x}
remplacera tous%
avec\x
.bash: 0m3.767s python: 0m0.200s
(python un liner ci-dessous: stackoverflow.com/a/21693459/1695680):
de la documentation? J'ai pensé:
était un no-op en bashGNU awk
Ou
Utilisation de awk printf pour urldecode texte
awk
, tandis que dans un couple commercialeawk
implémentations, cette fonctionchr()
n'est pas disponible. BTW, vous pouvez également omettre le--include|-i
déclaration et l'utilisation@load "ordchr"
directement dans votre code. (trouvé via RTFM ;-))si vous êtes un python développeur, ce peut-être preferer
urllib est professionnel de la manutention, il
echo "%21%20" | python -c "import sys; from urllib.parse import unquote; print(unquote(sys.stdin.read()));"
C'est ce qui semble fonctionner pour moi.
Remplacement de '+'s avec des espaces, et le signe % avec "\x " s'échappe, et en laissant l'écho interpréter le \x s'échappe à l'aide de l'option '-e' option n'a pas de travail. Pour une raison quelconque, la commande cat a l'impression de l' % signe que sa propre forme codée %25. Donc, sed était tout simplement le remplacement de 25% par \x25. Lorsque l'option-e a été utilisé, c'était tout simplement l'évaluation de \x25 en % et le résultat était le même que l'original.
Trace:
Original: Mozilla%2F5.0%20%28Macintosh%3B%20 U%3B%20Intel%20Mac%20OS%20X%2010.6%3B%20en
sed: Mozilla\x252F5.0\x2520\x2528Macintosh\x253B\x2520U\x253B\x2520Intel\x2520Mac\x2520OS\x2520X\x252010.6\x253B\x2520en
echo-e: Mozilla%2F5.0%20%28Macintosh%3B%20 U%3B%20Intel%20Mac%20OS%20X%2010.6%3B%20en
Correctif: ignorer Essentiellement les 2 caractères après le % de sed.
sed: Mozilla\x2F5.0\x20\x28Macintosh\x3B\x20U\x3B\x20Intel\x20Mac\x20OS\x20X\x2010.6\x3B\x20en
echo-e: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; fr
Pas sûr de ce que les complications cela aurait pour conséquence, après de nombreux essais, mais fonctionne pour l'instant.
\1
après\\x
commeecho -e "$(sed 's/+/ /g;s/%\(..\)/\\x\1/g;')"
\1
est manquant. J'ai édité la réponse de l'inclure. (Plus quelques petites mise en forme de la grammaire des modifications pour répondre à de 6 caractères minimum de modifier exigence.)Avec BASH, pour lire le pour cent URL encodée à partir de la norme et de décoder:
Appuyez sur CTRL-D pour le signal de la fin de fichier(EOF) et quitter normalement.
Vous pouvez décoder le contenu d'un fichier en paramètre le fichier à la norme en:
Vous pouvez décoder entrée à partir d'un tuyau, par exemple:
REPLY
égal à la ligne de texte qu'il vient de lire.${REPLY//%/\\x}
remplace toutes les occurrences de '%' avec '\x'.echo -e
interprète\xNN
que le caractère ASCII avec la valeur hexadécimale deNN
.Le ci-dessus ne change pas '+' a'. Pour changer ' + '' a aussi, comme invité réponse:
:
est un BASH builtin commande. Ici, il faut juste dans un seul argument et ne fait rien avec elle._
est un paramètre spécial qui est égal au dernier argument de la commande précédente, après l'argument de l'expansion. C'est la valeur deREPLY
avec toutes les instances de '%' remplacé par '\x'.${_//+/}
remplace toutes les occurrences de '+' à ' '.Il utilise seulement BASH et de ne pas commencer tout autre processus similaire à l'invité de la réponse.
Avec
-i
met à jour les fichiers en place (certainssed
implémentations ont emprunté que deperl
) avec.back
que la sauvegarde de l'extension.s/x/y/e
substitutsx
avec le eévaluation de lay
code perl.Le code perl dans ce cas utilise
pack
pour emballer le nombre hexadécimal capturé dans$1
(première paire de parenthèses dans l'expression rationnelle) que le caractère correspondant.Une alternative à
pack
est d'utiliserchr(hex($1))
:Si disponible, vous pouvez également utiliser
uri_unescape()
deURI::Escape
:Script Bash pour le faire en natif Bash (original source):
Si vous voulez urldecode contenu d'un fichier, il suffit de mettre le contenu du fichier comme argument.
Voici un test qui va exécuter arrêter si la décodé le contenu des fichiers codés diffère (si elle tourne pendant quelques secondes, le script fonctionne probablement correctement):
Si vous avez php installé sur votre serveur, vous pouvez "chat" ou encore "queue" de n'importe quel fichier, avec l'url encodées très facilement.
-R
avant, JUSQU'à environ$argn
(et$argi
)! Référence (^F-R
): php.net/manual/en/features.commandline.options.phpComme @barti_ddu dit dans les commentaires,
\x
"devrait être [double]échappé".Plutôt que de mélanger jusqu'Bash et sed, je voudrais faire cela tout en Python. Voici un premier montage de comment:
time
est votre ami.Avec GNU
awk
:Voici une solution qui est fait dans le plus pur bash où l'entrée et la sortie sont variables bash. Il va décoder '+' comme un espace et d'utiliser le '%20' de l'espace, ainsi que d'autres %les caractères encodés.
sed
n'est pas pur Bash; ce qui engendre un autre processus.Mise à jour Jay réponse pour Python 3.5+:
echo "%31+%32%0A%33+%34" | python -c "import sys; from urllib.parse import unquote ; print(unquote(sys.stdin.read()))"
Encore, brendan bash solution avec explication semble plus direct et le plus élégant.
L'expansion de
https://stackoverflow.com/a/37840948/8142470
de travailler avec des entités HTML
(argument doit être cité)
Confronté à un problème similaire, mon idée initiale était d'utiliser urldecode à partir de PHP dans un script permettant de lire stdin ou certains-tel, mais je suis tombée sur cette idée. Toutes les réponses semblent avoir beaucoup de texte, mais pas de réelle solution. L'idée est bonne mais, et c'est incroyablement facile de se mettre au travail:
La clé pour faire ce travail est double échappement \x (ce qui a été déjà mentionné).
Je voulais juste partager cette autre solution, pur bash:
Une version légèrement modifiée de l'Python réponse qui accepte une entrée et une sortie de fichier en une seule ligne.