Как заменить все процентные подстроки UTF-8 простым текстом UTF-8?

9

У меня есть HTML-файл с большим количеством%-кодированного текста UTF-8 в URL.

Например, «% D1% 80% D0% B5% D1% 81% D1% 83% D1% 80% D1% 81% D1% 8B» означает «ресурсы» («ресурсы» на русском языке).

Задача состоит в том, чтобы заменить все такие подстроки читаемым текстом UTF-8.

Чтобы упростить задачу, мы можем рассмотреть, что %в файле нет другого использования знака. Буквы могут быть как прописными, так и строчными.

Я подозреваю , что это может быть сделано элегантно с sed, perl, awkили что - то , но не знаю , как.

Это веб-приложение, кажется, делает трюк с текстом, который вы вставляете туда.

Иван
источник

Ответы:

9

При использовании bash, zsh, GNU echo или некоторых реализаций ksh в некоторых системах это можно декодировать, просто echo -eзаменив все %на \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: ресурсы

(Предполагается, что сама строка не содержит символов обратной косой черты и не является одним из параметров, поддерживаемых вашей echoкомандой)

Как отмечает @JoshLee, «предостережения от эха» можно избежать, используя непосредственно:

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

вместо этого непосредственно за первой командой.

LiuYan 刘 研
источник
Обратите внимание, что это элегантное решение будет работать с любой кодировкой, а не только с UTF-8 (т. Е. Избавиться от кодировок для ~ и других. Еще один трюк, добавленный в мой набор инструментов. Спасибо!
vonbrand
5

С perl:

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

Или с URI::Escape:

perl -MURI::Escape -pe '$_=uri_unescape$_'
Стефан Шазелас
источник
Мне это нравится, потому что я могу передать все, что захочу, благодаря $_ gnu.org/software/bash/manual/html_node/Special-Parameters.html
Nemo
@ Немо, $_вот perl, а $_не bash. В сочетании с этой -pопцией выражение perl запускается для каждой входной записи (записи, считываемые из файлов, заданных в качестве аргумента или стандартного ввода, если аргумент не указан), с текущей записью, хранящейся в $_. Это похоже на awk's $0.
Стефан Шазелас
0

Существует программа под названием, convmvкоторая может помочь вам.

Просто используйте convmv --unescape /some_path/target_file. Это будет делать всухую.

После подтверждения используйте, convmv --notest --unescape /some_path/target_fileчтобы продолжить.

Домашняя страница этой программы: http://j3e.de/linux/convmv/

Звезда Бриллиант
источник