Использование sed для преобразования шестнадцатеричных символов в файл дампа postgresql

Я работаю над переносом нескольких баз данных с сервера Postgresql 8.3 на сервер Postgresql 8.4. До сих пор это работало нормально, но одна база доставила мне некоторые неприятности. База данных указана в кодировке Unicode на 8.3-сервере, но каким-то образом клиентской программе удалось внедрить в нее некоторые недопустимые данные Unicode.

Когда я делаю обычный дамп и восстановление, используя пользовательский формат postgres, новый сервер не принимает его, жалуясь на ошибки юникода.

Мой план состоит в том, чтобы сделать простой текстовый дамп базы данных, а затем использовать sed, чтобы заменить недопустимые символы ничем (они не нужны). Но как заставить sed работать с шестнадцатеричными / двоичными значениями в файле?

6 ответов

Типичным решением является использование iconv -c,

Согласно ответу Питера, использование iconv является типичным решением, которое большинство людей используют для очистки неверных данных. Если вы хотите провести некоторый анализ данных заранее (и, возможно, очистить их в исходной базе данных), вы можете использовать следующий https://github.com/xzilla/utf8checker чтобы найти место возникновения проблемы.

Коллега указал мне в сторону Perl:

cat databasedump.sql | perl -pi -e 's / \ xc3 \ xa9 // g;' > fixeddatabasedump.sql

Хорошо, так что это не sed, но, по крайней мере, синтаксис более или менее такой же.

Согласно бинарной замене sed на stackoverflow, лучшая ставка, которую вы видели, - это пройти hexdump:

hexdump input | sed -e "..." | xxd -r -p output

Это лишит всех персонажей, которые находятся за пределами диапазона 0x32 (пробел) в 0x7e (Тильда):

someprog | LANG=C sed 's/[\x00-\x31\x7f-\xff]//g'

Вы можете использовать другие диапазоны символов, чтобы быть более избирательным.

tr -d '[:xdigit:]' < old_database > new_database также может работать.
tr -d удаляет только '[:xdigit:]' шестнадцатеричные символы

Другие вопросы по тегам