Модераторы: ginnie, korob2001
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как скопировать файл с кириллицей в названии? 
:(
    Опции темы
ijin
Дата 10.6.2009, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 10.6.2009

Репутация: нет
Всего: нет



Здравствуйте. Помогите пожалуйста подружить перл с кириллицей под Виндой.
Я хотел написать программу, которая скопирует файлы, содержащие в названии слово "результат"  в файл  "(номер)_русский.txt". Если использовать файлы с латинскими названиями, то все работает  (см первая часть программы). С файлами называнными кирилицей - облом. 

В гугле искал, базовые танцы с бубном проводил (см результаты для разных кодировок). Использую Windows XP, ActiveState Perl 5.10. , Notepad (ASNI or utf8 or uincode) и обычный cmd.exe (в смысле без /u )

Что исправить в программе?
В какой кодировке сохранять текст в блокноте?
Использовать ли cmd.exe /u ?
Какие модули нужно поставить?

 Заранее спасибо.

Код

 # кодировки здесь, например use encoding 'cp1251';

open(DIRLIST, "DIR /b|"); @list = <DIRLIST>; close(DIRLIST); #получить список файлов        

$i=1;                                   #счетчик для файлов
$search = "result";
foreach (@list) { chomp($file=$_);
if ( /$search/){                         #если имя файла содержит "result"
$command = "copy $file " . $i . "_ok.txt"; 
system($command);                        #скопируй файл в (номер)_ok.txt
print "command is $command abcde \n";    #проверка кодировки 
$i++; }}                      
                                         #пока все хорошо

print @list;

$search = "результат"; 
print "ищем $search \n";                 #            Облом Здесь
foreach (@list) { chomp($file=$_);
if ( /$search/){                         #если имя файла содержит "результат"
$command = "copy $file " . $i . "_русский.txt"; 
system($command);                        #скопируй файл в (номер)_русский.txt
print "команда $command абвгдежз \n";    #проверка кодировки (сюда прога не заходит)  
$i++; }}                                                 


Результаты: зависят от кодировки, но программа никогда не работает

 Без кодировки  => 
 ш∙хь Ёхчєы№ЄрЄ  (вместо "ищем результат")

use encoding "ru_RU.CP1251"; ||  use encoding 'cp1251'; =>
"\x{00a8}" does not map to cp1251 at C:\test\copy.pl line 15.

use encoding 'utf-8'; =>
 Malformed UTF-8 character (unexpected non-continuation byte
ter start byte 0xf0) at C:\test\copy.pl line 15.

use encoding 'cp1251', STDOUT => 'cp866'; =>
"\x{00a8}" does not map to cp866 at C:\test\copy.pl line 15. 
ищем результат                   #результат не найден







Это сообщение отредактировал(а) ijin - 10.6.2009, 12:49
PM MAIL   Вверх
ijin
Дата 12.6.2009, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 10.6.2009

Репутация: нет
Всего: нет



Товарищи, помогите пожалуйста решить эту проблему. Я честно честно пытался решить ее сам, но не смог. Где в программе ошибка? Без поддержки имен файлов кириллицей Перл Perl не позволяет сделать очень многое.
Заранее спасибо.
PM MAIL   Вверх
shamber
Дата 13.6.2009, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1422
Регистрация: 5.9.2006
Где: Россия

Репутация: 1
Всего: 18



Кто ж Вас так учил код так жестко нечитабельно оформлять?
Зачем в system используете? 
По поводу крякозябр, все очень просто используйте модуль Convert::Cyrillic

Чуток поиздевался над кодом smile
Код

use Convert::Cyrillic;

my $dirname = "./b";
# работаем с директориями на perl :)
opendir ( DIR, $dirname ) || die "Error in opening dir $dirname\n";
while( ($filename = readdir(DIR))){
    push @list,$filename;
}
closedir(DIR);
      
$i=1;                                   #счетчик для файлов
$search = "result";
foreach (@list) { 
    chomp($file=$_);
    if ( /$search/){                         #если имя файла содержит "result"
        # почитайте как средствами перл скопировать файл :)
        #$command = "copy $file " . $i . "_ok.txt"; 
        #system($command);                        #скопируй файл в (номер)_ok.txt
    
         print "command is $command abcde \n";    #проверка кодировки 
         $i++; 
      }
    }                      
                                         #пока все хорошо
#print @list;
$search = "результат";
my $str =  "ищем $search \n";                 #            Облом Здесь Уже Нет
print Convert::Cyrillic::cstocs ("WIN", "DOS", $str);
foreach (@list) { 
    chomp($file=$_);
    if ( /$search/){                         #если имя файла содержит "результат"
          #тот же коммент что и выше
          #$command = "copy $file " . $i . "_русский.txt"; 
          #system($command);                        #скопируй файл в (номер)_русский.txt
       my $str = "команда $command абвгдежз \n";
          print   Convert::Cyrillic::cstocs ("WIN", "DOS", $str);   #проверка кодировки (сюда прога не заходит)  
          $i++; 
      }
    }                                                 

да и еще в начале кода добавляйте  use strict;

Это сообщение отредактировал(а) shamber - 13.6.2009, 00:14
PM MAIL Jabber   Вверх
mvsgt
Дата 14.6.2009, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 27.3.2009

Репутация: нет
Всего: 1



Я бы ещё использовал модули File::Copy и File::Slurp, а то программа совершенно непонятная получается. И проверял на пробелы, директории, линки...
PM MAIL   Вверх
ijin
Дата 14.6.2009, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 10.6.2009

Репутация: нет
Всего: нет



Огромное спасибо, сейчас поставлю модули!
Цитата
Кто ж Вас так учил код так жестко нечитабельно оформлять?

Гуру или курса по Perl у меня не было. Единственный семинар был по Перлу под линуксом. Я учился у Google.

Посоветуйте книгу на тему "Как создать читабельную программу на Перле". А то я в своей проге - "крестики-нолики" с трудом разбираюсь.

И еще, под виндой выражение #!/usr/local/bin/perl не имеет смысла, но и не вредит. Верно?

Спасибо за помощь.



Это сообщение отредактировал(а) ijin - 14.6.2009, 19:53
PM MAIL   Вверх
shamber
Дата 14.6.2009, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1422
Регистрация: 5.9.2006
Где: Россия

Репутация: 1
Всего: 18



по оформлению посмотрите на perltidy

Это сообщение отредактировал(а) shamber - 14.6.2009, 22:08
PM MAIL Jabber   Вверх
ijin
Дата 14.6.2009, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 10.6.2009

Репутация: нет
Всего: нет



Поискал Convert::Cyrillic; 

В репозиториях activestate Perl не нашел. Скачать отсюда http://www.neystadt.org/cyrillic/ в разделе download. Этот модуль просит unicode/Map8.pm

Какой-то Map8.pm я скачал отсюда http://cpansearch.perl.org/src/GAAS/Unicod...p8-0.12/Map8.pm

Теперь прога говорит Can't locate loadable object for module Unicode::Map8 in @INC

У меня такой вопрос. Как пройти этот квест? 


PM MAIL   Вверх
shamber
Дата 15.6.2009, 00:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1422
Регистрация: 5.9.2006
Где: Россия

Репутация: 1
Всего: 18



ppm не пробовали?

Добавлено через 5 минут и 48 секунд
Unicode::Map8 там точно есть
PM MAIL Jabber   Вверх
ijin
Дата 15.6.2009, 01:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 10.6.2009

Репутация: нет
Всего: нет



Unicode:Map там есть. И Unicode-UTF8simple там есть. А вот Unicode:Map8 в 5.10 ActiveState Perl Package Manager нет. Какие репозитории нужно добавить?

Это сообщение отредактировал(а) ijin - 15.6.2009, 01:21
PM MAIL   Вверх
ijin
Дата 15.6.2009, 08:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 10.6.2009

Репутация: нет
Всего: нет



Новости с поля боя. 
Переставил Перл, нашел Map8.  Строка my $dirname = "./b"; выдает Error in opening dir ./b . Но работает строка  
Код
 open(DIRLIST, "DIR /b|"); @list = <DIRLIST>; close(DIRLIST);

Далее, т.к. "Спасение утопающих дело рук самих утопающих" отвечаю на мой вопрос. 
Для работы с русским языком Перлу нужен модуль перекодировки. Вариантов перекодировки* всего три: Не перекодировать, win - dos и dos - win. 

Нам понадобится 
а. Установить модуль Convert::Cyrillic и Map8.
б. Объявить Convert::Cyrillic в начале проги
в. Все запросы Перл->Система надо перекодировать по схеме
$Запрос_Виндам =  Convert::Cyrillic::cstocs ("WIN", "DOS", $Переменная_перла );
Все запросы Система->Перл надо перекодировать по схеме
$Переменная_перла =  Convert::Cyrillic::cstocs ("DOS", "WIN",  $Ответ_Винды );

Пошаговая инструкция на приере  ActiveState Perl
1. Пишем прогу (см ниже) и запускаем под cmd. Текст проги: 
Код

use  Convert::Cyrillic; print "hi";

Если на экране появится hi , то у вас есть этот модуль, переходите к пункту 7
Если нет, то прога скажет Can't locate Convert/Cyrillic.pm in @INC (@INC contains: C:/Perl/site/lib C:/Perl/lib .) at .... Тогда запоминаем директории и идем к пункту 2.
2. В Perl Package Manager выбираем "все пакеты" и ищем Map8. Если не нашли - добавляем репозитории.
3. Скачиваем поддержку кириллицы (обычно файл cyrillic-1.xx.tar.gz), например отюда http://search.cpan.org/~jneystadt/cyrillic...ert/Cyrillic.pm
4. Распаковываем архив и кладем папки и файлы (Convert, Lingua, Makefile.PL и т.д.) в директорию из пункта 1 (в примере в C:/Perl/site/lib).
5. В cmd идем в C:/Perl/site/lib и запускаем  Makefile.PL Смотрим, все ли модули он поставил.
6. Опять запускаем прогу из пункта 1. Теперь она должна написать  hi.
7. Создаем папку, в папке файлы-пустышки проверка.txt и dummy.txt . В ту же папку записываем прогу, текст которой приведен ниже. Смотрим как правильно кодировать для вывода на экран, в винду, и т.д.

Внимание, 
Проге нужны файлы проверка.txt и dummy.txt (не важно с чем, хоть пустые)
Прога создаст полдюжины текстовых файлов (удалите их). 
Стиль кода может травмировать слабонервных эстетов. Зато программа работает.

Код

use Convert::Cyrillic;    #Перекодировочный модуль
use File::Copy;           #Модуль для копирования по-хацкерски 

#Проверим латиницу

$latin1 = "dummy.txt"; $latin2 = "test_ok.txt";
copy($latin1, $latin2) or die "Copy failed: $!"; #латиница, так что копирование работает
print "from $latin1 to $latin2 \n\n";              #и текст выводится правильно
print "Time for Cyrillic \n"; 

#Выведем на экран килиллицу

print "привет, козяблики \n";                 # Козяблики
$line = "привет, кириллица!";                 # Записываем
$line1= Convert::Cyrillic::cstocs ("WIN", "DOS", $line);    #Кодируем
print "$line1 \n";                                           #Получили кириллицу             
print Convert::Cyrillic::cstocs ("WIN", "DOS", "...Можно и так... \n\n"); # Тоже кириллица

#Создадим список файлов в директории на будущее

open(DIRLIST, "DIR /b|"); @list = <DIRLIST>; close(DIRLIST); #Список файлов в директории
print "Cyrillic letters are ok\n @list \n"; #Вывести список файлов, выводит кириллицей

#Сменим кодировку для общения с Windows

$cyr1 = "проверка.txt"; $cyr2 = "по_хацкерски.txt";
copy($cyr1, $cyr2) or die "Copy failed: $!"; #Эта строка сработает
$naive = "copy проверка.txt по_простому.txt";  system($naive);

print "\n\t Check the file copies \n";

$i=0; $search = "проверка.txt"; #Сравнение данных из Винды и из Перла

foreach (@list) { chomp($file=$_);
if ( /$search/){
print "matching encoding \n";$i++;}}  # И не надейтесь, т.к. нужна перекодировка
if ( $i == 0 ) {print "no encoding -\> mismatch \n";}

$i=0; $search = Convert::Cyrillic::cstocs ("WIN", "DOS", $search); #используем кодировку
foreach (@list) { chomp($file=$_);
if ( /$search/){  #И совпадения находятся
print "Win to Doc encoding -\> match \n";$i++;}}
if ( $i == 0 ) {print "encoding mismatch \n";}

print "\n\t Check string matching \n";

#Протестим вывод в файл

$output_p1 = "no encoding без кодировки \n";
$output_p2 = Convert::Cyrillic::cstocs ("WIN", "DOS", "win_dos вин в дос кодировка \n");
$output_p3 = Convert::Cyrillic::cstocs ("DOS", "WIN", "dos_win дос в вин кодировка \n");
$output_p = $output_p1 . $output_p2 . $output_p3 ;

open ( OUT, " >perl_chk.txt " ); print OUT $output_p; close ( OUT ); 
print "\n\t check printing to file \n";

#кириллица по пути из cmd -> Perl -> file

$cmd_line = "dir \>\> cmd_out.txt";
system($cmd_line);                         #Получились козяблики. Надо было выводить в переменную Perl
print "\n\t check kozyabliki in cmd_out.txt \n";

#лечение козябликов в cmd_out.txt. Можно вылечить, но лучше не допускать.

open ( IN, " <cmd_out.txt " ); 
open ( FIXED , " >>fixed.txt " ); 
while (<IN>) 
{ print FIXED Convert::Cyrillic::cstocs ("DOS", "WIN", $_ );}; 
close (IN); close (FIXED);
print "\n\t check fixed.txt \n";
<stdin>;


___
* В первом приближении, для работы с кириллицей

Это сообщение отредактировал(а) ijin - 15.6.2009, 08:26
PM MAIL   Вверх
shamber
Дата 15.6.2009, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1422
Регистрация: 5.9.2006
Где: Россия

Репутация: 1
Всего: 18



Цитата(ijin @  15.6.2009,  08:04 Найти цитируемый пост)
my $dirname = "./b"; выдает Error in opening dir ./b
 потому что путь к директории задан не верно.
У меня директория b находилась там же где и сам скрипт. т.е. путь относительный. можно было задать и абсолютный путь. И если его задать, не забывая что слеши нужно ставить  такие -> / то все будет ок.
И вот этот код работает прекрасно smile

Цитата(ijin @  15.6.2009,  08:04 Найти цитируемый пост)
Код

$i=0; $search = "проверка.txt"; #Сравнение данных из Винды и из Перла
foreach (@list) { chomp($file=$_);
if ( /$search/){
print "matching encoding \n";$i++;}}  # И не надейтесь, т.к. нужна перекодировка
if ( $i == 0 ) {print "no encoding -\> mismatch \n";}



Тот код который я приводил в начале работает и без перекодировки smile Именно поиск. А вот вывод в консоль полюбому переконвертировать.



Это сообщение отредактировал(а) shamber - 15.6.2009, 11:20
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl: Системное программирование"
korob2001
sharq
  • В этом разделе обсуждаются вопросы относящиеся только к системному программированию на Perl
  • Если ваш вопрос не относится к системному или CGI программированию, задавайте его в общем разделе
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0525 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.