qkowlew: На Зилантконе меня сфоткали мыльницей. Мыльницам не позирую! (Default)
[personal profile] qkowlew
После не лучшим образом сделанного преобразования html-ек из православной кодировки КОИ8-R в не менее православную ныне UTF-8 (на некоторых страницах мемориального зеркала Свиридова) потребовалось совершить:

perl -p -i.scrback -e 'use utf8; tr/√┘╚╩/—…«»/'

UPD3: Вот так работает. Спасибо коллеге shaplov

cat vskon-orig.htm | perl -e '
binmode STDIN, ":utf8";
binmode STDOUT, ":utf8";
use utf8;
while(my $a=<STDIN>) {
$a=~tr/√┘╚╩/—…«»/;
print $a
}' >vskon-result.htm




tr же строго побайтовый и не работает. Консоль UTF-8

Принимаю помощь зала как:
- правильно
- проще всего

UPD2: Теперь я вполне понимаю, почему perl как массовый язык программирования на вебе ушёл в прошлое, уступив намного более ублюдочному по сути PHP. Проблемы с переходом на UTF-8 оказались непреодолимы для большинства разработчиков. :(

UPD1: про мои ОС и перл:
# perl -v

This is perl, v5.10.1 (*) built for i386-freebsd-64int

Copyright 1987-2009, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
# uname -a
FreeBSD 8.2-RELEASE-p3 FreeBSD 8.2-RELEASE-p3 #0: Tue Sep 27 18:07:27 UTC 2011     root@i386-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC  i386
# locale
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_ALL=ru_RU.UTF-8

Date: 2012-Apr-22, Sunday 08:48 (UTC)
From: [identity profile] dmarck.livejournal.com
OS? Может быть, у тебя tr(1) wchar-compatible?

Date: 2012-Apr-22, Sunday 09:06 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
если один раз и не думать, то проще вего написать несколько

$text=~ s/√/—/g;
$text=~ s/┘/…/g;

и т.п.

C tr вечно встречаются проблемы с уникодом...
Правда последнюю проблему которую встречал проявлялась в 5.8. и только если процесс пошел в тред.
Но для одно раза проче юзать s/// он точно работает

Date: 2012-Apr-22, Sunday 09:14 (UTC)
From: [identity profile] qkowlew.livejournal.com
Не работает.

Date: 2012-Apr-22, Sunday 09:15 (UTC)
From: [identity profile] qkowlew.livejournal.com
'use utf8; s/╚/«/g'

не заменяет.

Date: 2012-Apr-22, Sunday 09:23 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
echo 'аа-бб-аа-цц' | perl -e 'binmode STDIN, ":utf8"; use utf8; my $x = ; $x=~tr/а/б/; print $x;'
Edited Date: 2012-Apr-22, Sunday 09:27 (UTC)

Date: 2012-Apr-22, Sunday 09:29 (UTC)
From: [identity profile] qkowlew.livejournal.com
Часть символов заменяет, часть нет.
Ругается:
Wide character in print at -e line 1, line 189.
Wide character in print, line 189.

Date: 2012-Apr-22, Sunday 09:31 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
Добавь еще
binmode STDOUT, ":utf8";
ругаться не будет.

Date: 2012-Apr-22, Sunday 09:32 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
А почему не заменяет -- не знаю... :-/
Должон заменять...

Date: 2012-Apr-22, Sunday 09:32 (UTC)
From: [identity profile] qkowlew.livejournal.com
оригинал:
конвенты были организованы под Харьковом (╚Чугункон╩) под Нижним Новгородом
(╚ВОЛК╩, Волжский Конвент), в Питере (Фестиваль Ролевого Костюма) и Самаре
(╚СОК╩, самарский открытый конвент). У суровых реконструкторов, главным
событием стал минский  турнир-фестиваль ╚Белый Замок╩, и наконец,

текст программы:
'binmode STDIN, ":utf8"; use utf8; my $a=; $a=~tr/√┘╚╩/—…«»/; print $a'

результат:
конвенты были организованы под Харьковом (╚Чугункон╩) под Нижним Новгородом
событием стал минский  турнир-фестиваль «Белый Замок», и наконец,

Date: 2012-Apr-22, Sunday 09:35 (UTC)
From: [identity profile] qkowlew.livejournal.com
'binmode STDIN, ":utf8"; binmode STDOUT, ":utf8"; use utf8; my $a=<STDIN>; $a=~tr/√┘╚╩/—…«»/; print $a'

Date: 2012-Apr-22, Sunday 09:39 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
'binmode STDOUT, ":utf8"; binmode STDIN, ":utf8"; use utf8; while (my $x=<STDIN>) { $x=~tr/√┘╚╩/—…«»/; print $x}'

Я не умею однострочники писать :-)
Это как-то компактнее можно выразить....
Edited Date: 2012-Apr-22, Sunday 09:40 (UTC)

Date: 2012-Apr-22, Sunday 09:42 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
Подозреваю что если воткнуть binmode STDOUT, ":utf8"; binmode STDIN, ":utf8" в твой пример, все заработает как надо.

Date: 2012-Apr-22, Sunday 09:51 (UTC)
From: [identity profile] qkowlew.livejournal.com
Да воткнул давно уже.
просто в этом комменте (на который ты отвечаешь) случайно вставил старый вариант

Date: 2012-Apr-22, Sunday 09:50 (UTC)
From: [identity profile] qkowlew.livejournal.com
А в чём проблема с однострочником? 8-О
Ну можно не в одну строку:

'
binmode STDOUT, ":utf8";
binmode STDIN, ":utf8";
use utf8;
while (my $x=) { $x=~tr/√┘╚╩/—…«»/; print $x}

'

Всё равно ж херня получается - строки тасуются в выдаче - см. мой коммент ниже.

Date: 2012-Apr-22, Sunday 09:53 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
Там есть специальная нотация которая позволяет записать все это гораздо компактнее...

Пришли тогда мне файл на n -at- shaplov dot ru чтоли...

Date: 2012-Apr-22, Sunday 09:54 (UTC)
From: [identity profile] qkowlew.livejournal.com
При чём тут "компактнее"??!
Посмотри что с последовательностью строк в выдаче.

Date: 2012-Apr-22, Sunday 09:57 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
Меня это крайне удивляет.
Поэтому я сначала хотел бы получить оригинальный файл, чтобы через копипаст ничего не терялось, а потом если ты не будешь против, оригинальный шелл (или аналогичный оригинальному). Потому как у меня с порядком строк -- все в порядке...

Date: 2012-Apr-22, Sunday 10:18 (UTC)
From: [identity profile] qkowlew.livejournal.com
оригинал: http://gfns.net/asw/vskon-orig.htm
результат: http://gfns.net/asw/vskon-result.htm
первая строка оригинала оказалась в конце результата.

в шелле:
cat vskon-orig.htm | perl -p -e '
binmode STDIN, ":utf8";
binmode STDOUT, ":utf8";
use utf8;
while(my $a=<STDIN>) {
$a=~tr/√┘╚╩/—…«»/;
print $a
}' >vskon-result.htm

Date: 2012-Apr-22, Sunday 10:28 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
-p убери.

Date: 2012-Apr-22, Sunday 10:31 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
Это как раз артифакт от однострочника который я не умею :-)

Date: 2012-Apr-22, Sunday 09:44 (UTC)
From: [identity profile] qkowlew.livejournal.com
Даже круче!
оригинал:
Таким образом в феврале и ╚рядом╩ с ним прошло сразу несколько мероприятий,^M
причем самых разных направлений и в самых разных регионах.  Ролевые^M
конвенты были организованы под Харьковом (╚Чугункон╩) под Нижним Новгородом^M
(╚ВОЛК╩, Волжский Конвент), в Питере (Фестиваль Ролевого Костюма) и Самаре^M
(╚СОК╩, самарский открытый конвент). У суровых реконструкторов, главным^M
событием стал минский  турнир-фестиваль ╚Белый Замок╩, и наконец,^M
╚книжные фэны╩ провели РОСКОН √ классический конвент с участием знаменитых^M
писателей, заматеревших любителей и себе на уме издателей, зорко высматривающих^
молодые таланты.^M

результат:
Таким образом в феврале и ╚рядом╩ с ним прошло сразу несколько мероприятий,^M
(«ВОЛК», Волжский Конвент), в Питере (Фестиваль Ролевого Костюма) и Самаре^M
конвенты были организованы под Харьковом (╚Чугункон╩) под Нижним Новгородом^M
событием стал минский  турнир-фестиваль «Белый Замок», и наконец,^M
(╚СОК╩, самарский открытый конвент). У суровых реконструкторов, главным^M
писателей, заматеревших любителей и себе на уме издателей, зорко высматривающих^
╚книжные фэны╩ провели РОСКОН √ классический конвент с участием знаменитых^M


^M - это возвраты каретки. :)

Date: 2012-Apr-22, Sunday 09:50 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
Тот пример который я тебе прислал, не был полноценной программой, и считывал только первую строку и конвертировал.

Последний отправленный мной пример считывает весь файл.
У меня с точностью до nbsp; все им конвертнулось...

Date: 2012-Apr-22, Sunday 09:57 (UTC)
From: [identity profile] qkowlew.livejournal.com
А. Теперь дошло.

Date: 2012-Apr-22, Sunday 10:13 (UTC)
From: [identity profile] qkowlew.livejournal.com
Сравни исходники
http://gfns.net/asw/vskon-orig.htm
и
http://gfns.net/asw/vskon-result.htm

(это чтобы include virtual не примешивалось)

Date: 2012-Apr-22, Sunday 09:17 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
Еще не плохо посмотреть что именно ты обрабатываешь, и есть ли на нем utf8 флаг...

Для этого есть хороший модуль Devel::Peek;

если ты это берешь со стандартного вывода, и не предпринимаешь особых усилий чтобы оно стало :utf8, то тогда оно считается байтовым, и замена utf8 символов внутри него не работает.

Date: 2012-Apr-22, Sunday 09:22 (UTC)
From: [identity profile] qkowlew.livejournal.com
то есть - прямого пути (настрока одной-N прагм)

преобразования из:
- имеем программу, текст ея в кодировке KOI8-R
- имеем исходные данные в кодировке KOI8-R
- имеем выход в кодировке KOI8-R

в:
- имеем ту же программу, текст ея в кодировке UTF-8
- имеем исходные данные в кодировке UTF-8
- имеем выход в кодировке UTF-8

нет.
есть только извращённые, с переписыванием каждой строки работы с регекспами?

Date: 2012-Apr-22, Sunday 09:25 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
Не понял твой вопрос.

Правильно работающий пример -- выше. Если речь идет о посимвольной замене уникодных символов приходящих на stdin

Date: 2012-Apr-22, Sunday 09:36 (UTC)
From: [identity profile] qkowlew.livejournal.com
Не работает. В том и прикол.
Имеем потерю двух строк и непреобразование части искомых символов.

Date: 2012-Apr-22, Sunday 09:29 (UTC)
ext_613079: Default userpic (Бритый небритый)
From: [identity profile] shaplov.livejournal.com
Прочитал еще раз:

Да, каждое открытие файла надо будет явно обозначать как открытие файла с уникодным контентом.
Увы.

Date: 2012-Apr-22, Sunday 15:55 (UTC)
From: [identity profile] arthin.livejournal.com
Для кода 'use utf8;'.
Для ввода-вывода 'use open qw/:utf8/; use open qw/:std :utf8/;'
Твой начальный пример это у меня чинит. Правда, только в файле скрипта, с -e почему-то не работает. Но с -e еще проще, там perl -C можно.

Date: 2012-Apr-22, Sunday 09:49 (UTC)
From: [identity profile] deemon.livejournal.com
не уверен, что до конца вник в проблему, но в похожих ситуациях меня много раз выручал банальный iconv

Date: 2012-Apr-22, Sunday 10:02 (UTC)
From: [identity profile] qkowlew.livejournal.com
Боюсь, Вы не прочли сообщение целиком.
1. Именно банальный iconv и превратил кавычки, тире и многоточие в псевдографику, а так как это было только на очень малой доле страниц сайта, я этого долго не замечал.
2. Мысль преобразовать обратно и снова туда, конечно, прекрасна. Однако в том и дело, что нужное мне действие - рутинная задача, тривиально решавшаяся "пока кодировки были однобайтовыми" стандартным способом. Я столкнулся с тем, что теперь, при "православной" кодировке UTF-8, перлом она должна решаться с вывертами.

Date: 2012-Apr-22, Sunday 11:32 (UTC)
From: [identity profile] besm6.livejournal.com
Perl уступил не PHP, а Python и Ruby, у которых раньше появились полноценные фреймворки.

Date: 2012-Apr-22, Sunday 19:31 (UTC)
From: [identity profile] qkowlew.livejournal.com
Я про массовое веб-программирование.
Как админ хостингового сервера я застал массовое программирование на Перле и на PHP
Массового применения питона и Руби не наблюдал.
Из имеющихся у меня (400), а также переезжавших ко мне или от меня (около 300) хостов:

Единичные случаи - Питона. То ли 2, то ли 4 - смотря как считать, по клиентам или по хостам.
4 случая серверной Явы
Ни одного - Руби

Date: 2012-Apr-23, Monday 04:34 (UTC)
From: [identity profile] besm6.livejournal.com
Я подозреваю, что дело в том, что те, кому нужно как следует - им и надежность нужна выше, чем ты предоставляешь. А в нише "как курица лапой" да, выигрывает PHP, просто потому что его больше. Но в этой нише проблем с UTF-8 (которые в PHP тоже есть) "программист" не замечает. У него другие проблемы...

Date: 2012-Apr-23, Monday 05:25 (UTC)
From: [identity profile] qkowlew.livejournal.com
Ты совершенно прав, я смотрю строго со своей колокольни.

в PHP + MySQL перевод с windows-1251 на utf-8 в подавляющем большинстве даже очень ракообразных самописных движков, с которыми я имел дело на серверах, сводился к максимум 4-м действиям:
- перекодировать iconv и перезалить дамп базы, проставив ему в начало set names utf8;
- перекодировать iconv файлы php
- проставить set names utf8 после mysql_connect
- убрать из .htaccess упоминания о кодировках, если были (они там, порой, оставались со времён "русского апача").

Ни одной ситуации вида "перестали работать регекспы" или "эта функция только побайтовая" не наблюдал. Одна ситуация вида "в cgi варианте работаем - в апаче нет" явно по причине перекодированных строк.

Date: 2012-Apr-23, Monday 14:28 (UTC)
From: [identity profile] besm6.livejournal.com
Что-то я подозреваю, что ни в одном из этих случаев содержательной обработки текста не было (обработка ASCII-разметки типа bbcode или *wiki не в счет - она в UTF-8, в отличие от других кодировок Unicode, столь же успешно делается и однобайтовыми средствами). Хотя я не спорю, танцы с UTF-8 в перле странны.

Date: 2012-Apr-23, Monday 14:38 (UTC)
From: [identity profile] qkowlew.livejournal.com
Ну почему же - шаблончики вида {{ЗАГОЛОВОК}} в одном из движков явно однобайтовыми операциями в утф-8 не кушаются

Date: 2012-Apr-23, Monday 16:19 (UTC)
From: [identity profile] besm6.livejournal.com
В смысле там в обработке еще и преобразование регистра? Потому что "{{, }} и то, что между ними", если не менять то, что между ними, кушается на ура.

Date: 2012-Apr-22, Sunday 11:38 (UTC)
From: [identity profile] ignik.livejournal.com
Вообще-то большинству разработчиков проблемы кои несколько индифферентны.

Беда perl'а в том, что на нём неудобно программировать методом cut/paste.

Date: 2012-Apr-22, Sunday 19:33 (UTC)
From: [identity profile] qkowlew.livejournal.com
Ну только не говорите мне, что у других алфавитов в перле всё хорошо при переходе на UTF-8 с однобайтовых кодировок, и не надо менять кода. :)

Date: 2012-Apr-22, Sunday 22:41 (UTC)
From: [identity profile] ignik.livejournal.com
Проблемы туземцев не волнуют шерифа...

Впрочем читать тут.

Date: 2012-Apr-23, Monday 05:28 (UTC)
From: [identity profile] qkowlew.livejournal.com
Это читал.