Comment remplacer toutes les sous-chaînes UTF-8 encodées en pourcentage par du texte UTF-8 ordinaire?

9

J'ai un fichier html avec beaucoup de texte UTF-8 encodé à% dans les URL.

Par exemple, "% D1% 80% D0% B5% D1% 81% D1% 83% D1% 80% D1% 81% D1% 8B" signifie "ресурсы" ("ressources" en russe).

La tâche consiste à remplacer toutes ces sous-chaînes par du texte UTF-8 lisible.

Pour simplifier la tâche, nous pouvons considérer qu'il n'y a pas d'autre %utilisation de signe dans le fichier. Les chiffres des lettres peuvent être en majuscules et en minuscules.

Je soupçonne que cela peut être fait avec élégance sed, perl, awkou quelque chose , mais ne savent pas comment.

Cette application Web semble faire l'affaire avec le texte que vous y collez.

Ivan
la source

Réponses:

9

Avec bash, zsh, GNU echo ou certaines implémentations de ksh sur certains systèmes, cela peut être décodé simplement en les echo -eremplaçant tous %par \x.

url_encoded_string="%D1%80%D0%B5%D1%81%D1%83%D1%80%D1%81%D1%8B"
temp_string=${url_encoded_string//%/\\x}

printf '%s\n' "$temp_string"
# output: \xD1\x80\xD0\xB5\xD1\x81\xD1\x83\xD1\x80\xD1\x81\xD1\x8B

echo -e "$temp_string"
# output: ресурсы

(Il suppose que la chaîne elle-même ne contient pas de barre oblique inverse et n'est pas l'une des options prises en charge par votre echocommande)

Comme le souligne @JoshLee également, la "mise en garde concernant l'écho" peut être évitée en utilisant directement:

printf ${url_encoded_string//%/\\x}

au lieu de cela directement derrière la première commande.

LiuYan 刘 研
la source
Notez que cette solution élégante fonctionnera avec n'importe quel encodage, pas seulement UTF-8 (c'est-à-dire, débarrassez-vous des encodages pour ~ et autres. Une autre astuce à ajouter à ma boîte à outils. Merci!
vonbrand
5

Avec perl:

perl -pe 's/%([0-9A-F]{2})/pack"H2",$1/gei'

Ou avec URI::Escape:

perl -MURI::Escape -pe '$_=uri_unescape$_'
Stéphane Chazelas
la source
J'adore ça parce que je peux le canaliser comme je veux grâce à $_ gnu.org/software/bash/manual/html_node/Special-Parameters.html
Nemo
@Nemo, $_voici perl's $_, non bash' s. En combinaison avec l' -poption, l'expression perl est exécutée pour chaque enregistrement d'entrée (enregistrements en cours de lecture à partir de fichiers donnés en argument ou stdin si aucun argument n'est fourni), l'enregistrement en cours étant stocké dans $_. C'est similaire à awkl » $0.
Stéphane Chazelas
0

Il existe un programme appelé convmvqui peut vous aider.

Utilisez simplement convmv --unescape /some_path/target_file. Il fera un essai à sec.

Une fois que vous avez confirmé, utilisez convmv --notest --unescape /some_path/target_filepour continuer.

La page d'accueil de ce programme est: http://j3e.de/linux/convmv/

Star Brilliant
la source