Эта проблема, вероятно, связана с несоответствием кодировки между входным файлом и сценарием awk.
Пожалуйста, обратите внимание, что, вероятно, существует (очень распространенная) путаница между ISO-8859-1 и Windows -1252 здесь. Образец html в исходном сообщении содержит символы em / en da sh, которые не являются частью макета ISO-8859-1 , поэтому он, безусловно, использует другую кодировку, вероятно, Windows -1252 (который является надмножеством ISO-8859-1, включая символы da sh), поскольку OP сообщил, что использует Ubuntu через уровень подсистемы Windows.
Я тогда Предположим, что входной файл html действительно закодирован как Windows -1252. Поэтому не-ASCII-символы (кодовые точки ≥ 128) используют только один байт.
Если программа awk загружается из файла, закодированного в UTF-8, или даже непосредственно набирается в окне терминала, которое использует UTF- После окончания кодирования, затем регулярные выражения и буквенные строки, встроенные в программу, также кодируются в UTF-8. Поэтому не-ASCII-символы используют несколько байтов.
Например, символ §
(кодовая точка 167 = 0xA7) представлен байтом A7
в Windows -1252 и последовательностью байтов. C2 A7
в UTF-8. Если вы используете gsub(/§/, "S")
в своей программе awk в кодировке UTF-8, то awk ищет последовательность C2 A7
во входном файле, который содержит только A7
. Это не будет соответствовать. Если вы (не) достаточно удачливы, чтобы персонаж Â
(кодовая точка 194 = 0xC2) зависал перед вашим §
.
Смена локали здесь не помогает, потому что она только сообщает awk, как для анализа входных данных (данных и программы), тогда как здесь вам нужно перекодировать либо данные, либо регулярные выражения. Чтобы это работало, вы должны иметь возможность указывать языковой стандарт данных независимо от языкового стандарта программы, который не поддерживается.
Итак, при условии, что ваша система настроена с UTF-8 locale и что ваш awk-скрипт использует эту локаль (независимо от того, загружен ли он из файла или введен в терминале), вот несколько методов, которые можно использовать для выравнивания входного файла и регулярных выражений в одной и той же кодировке, чтобы gsub
работал как и ожидалось.
Обратите внимание, что эти предложения относятся к вашей первой команде awk, поскольку она является источником проблемы. Последний канал для iconv
необходим только в том случае, если вы намеренно не преобразуете все специальные символы, которые могут иметь во входных данных, в html сущности. В противном случае вывод awk является простым ASCII, поэтому уже совместим с UTF-8.
Опция 1: преобразовать входной файл из Windows -1252 в UTF-8
Нет необходимости в другом iconv
шаг в этом случае в любом случае.
iconv -f WINDOWS-1252 t.html | awk '{
gsub(/charset=iso-8859-1/, "charset=UTF-8")
gsub(/\047/, "\\'")
gsub(/\*/, "\\*")
gsub(/–/, "\\–")
gsub(/—/, "\\—")
gsub(/§/, "\\§")
gsub(/«/, "\\«")
gsub(/»/, "\\»")
gsub(/¿/, "\\¿")
gsub(/Á/, "\\Á")
print
}'
Вариант 2: преобразовать программу awk из UTF-8 в Windows -1252
Поскольку программе awk тоже может быть интересно , Давайте используем замену процесса.
awk -f <(iconv -t WINDOWS-1252 <<'EOS'
{
gsub(/charset=iso-8859-1/, "charset=UTF-8")
gsub(/'/, "\\'")
gsub(/\*/, "\\*")
gsub(/–/, "\\–")
gsub(/—/, "\\—")
gsub(/§/, "\\§")
gsub(/«/, "\\«")
gsub(/»/, "\\»")
gsub(/¿/, "\\¿")
gsub(/Á/, "\\Á")
print
}
EOS
) t.html
Вариант 3: сохранить скрипт awk / schell в файле, закодированном в Windows -1252
... с вашим любимым инструментом.
Вариант 4: переключите кодировку сеанса терминала на Windows -1252
В случае, если вы, конечно, набираете / вставляете команду awk в терминале.
Обратите внимание, что это отличается от установки локали (LC_CTYPE). Я не знаю способ сделать это программно. Если кто-то знает, не стесняйтесь вносить свой вклад.
Вариант 5: в программе awk вообще избегайте использования символов, отличных от ASCII
В любом случае, на мой взгляд, это хорошая практика.
awk '{
gsub(/charset=iso-8859-1/, "charset=UTF-8")
gsub(/\047/, "\\'")
gsub(/\*/, "\\*")
gsub(/\226/, "\\–")
gsub(/\227/, "\\—")
gsub(/\247/, "\\§")
gsub(/\253/, "\\«")
gsub(/\273/, "\\»")
gsub(/\277/, "\\¿")
gsub(/\301/, "\\Á")
print
}' t.html