Всем доброго времени суток
Обнаружилась у меня интересная проблемка с моей книжной коллекцией. Я собираю ее постепенно (по мере прочтения) уже порядка 5 лет. Набралось пока гдето около 900-1000 книг от сотни авторов. Начал собирать еще для моего первого КПК на PocketPC (теперь это называется win mobile). Так как тогда флэшки стоили дороже то место я сурьезно экономил - все скачанные книги переводил в txt (обычно потому что doc читалки не поддерживали а про fb2 я еще не знал - да и в библиотеках его было мало выложено - а переводить в него часто криво получается) а потом сжимал в zip. Часто имя файла а потом и архива было названо по русски по имени произведения и к томуже с пробелами. И haalireader нормально все это читал. Теперь вместе с покупкой NokiaN800 соответственно перешел на FBreader (а незадолго перед этим с форточек на Debian) - и вот тут то и обнаружилась засада - читалка видит архив, названный по русски, нормально - но внутри него не видит файла (тож названного по русски) - хотя файл там точно есть - стал разбираться и поставил на свой домашний Debian нормальный FBReader(в смысле версию для i386 архитектуры). Обнаружилось кое что орригинальное - при распаковке файла в debian имя файла отображается какими то квадратиками, причем название архива выглядит нормально. И вот такой файл с именем квадратиками fbreader то и не видит - если файл уже в дебиане переназвать так же - то все нормально - как я понял это какая то проблема с кодировками между виндой и линухом - т. е. с cp1251 и utf8. Соответственно сама просьба - мне в принципе все равно как будут названы файлы - по русски там или транслитом - вот поэтому хочу написать скрипт который будет распаковывать архивы названные по русски переобразовывать имена в транслит и паковать назад(ручками переименовывать 500 файлов это как то муторно) - но прошу помощи в том как написать команду отбора этих файлов/архивов - я не очень силен в скриптах.
Может кто нить предложит какое нить еще решение - менее геморное - буду очень благодарен.
Всем спасибо
PS Уважаемые модераторы - возможно я создал тему не в том разделе (проблема многогранна и относиться не совсем к таблетке - просто впервые столкнулся именно на ней). Поэтому если Вам так покажется - перенесите ее пожалуйста в более подходящее место.
Неактивен
Мне видятся два варианта решения проблемы:
а) Обратиться к автору с вопросом(он сам русскоговорящий на сколько помню). Ему пофиксить эту проблему не сложно.
б) Написать скрипт. Сам скрипт написать не сложно, но нужно иметь несколько файлов для теста.
Вариант "а" предпочтительней ![]()
Неактивен
Вариант А конечно хорош - только сдается мне автор FBReader не в силах исправить это - но попробую ему написать. Вариант Б мне нравиться тем что все зависит только от меня а не от кого то еще и никого не нужно ждать - попробую куда-нить выложить несколько каталогов с книгами - потом ссылку оставлю.
Неактивен
--------------------------------------
find -iname "*.zip" -exec unzip {} \;
распакует все архивы в директории
------------------------------------------
$convmv -r --notest --nosmart -f cp1251 -t utf-8 filename
для перекодировки имени
попробуйте так на одном файлике - если всё ок /
$convmv -r --notest --nosmart -f cp1251 -t utf-8 *
в директории с файлами
Неактивен
find -iname "*.txt" -exec zip {}.zip {} \; упакует все файлы txt в архивы.
кто то может написал бы скрипт проще и красивше - но - можете попробовать так :
в той директории где лежат zip файлы - распаковываете все
затем перемещаете в сторону / удаляете .zip файлы $mv *.zip /home/user/book/
проводите перекодировку всех txt в директории
упаковываете все txt в zip
всё
Не знаю - есть ли у вас в именах пробелы и другие символы с которыми теоритически могут быть проблемы.
Неактивен
А в zip имена в cp1251? ИМХО там cp866.
Неактивен
find -iname "*.zip" -exec unzip {} \;
распакует все архивы в директории
я так понимаю что в текущей директории распакует - но у меня архивы с книгами раскиданы по директориям по имени авторов а подом по подпапкам с названием серии - т е получается до второй вложенности включительно, причем имена авторов и названия серий даны по русски и с пробелами. Выглядит примерно так(привел тока часть списка ибо он великоват)
alex@hc-deb-al:~/documents/Книги$ du -a ./ 428 ./Симмонс Дэн/Simmons_Giperion.zip 456 ./Симмонс Дэн/Simmons_Padenie_Giperiona.zip 888 ./Симмонс Дэн 360 ./Браславский Дмитрий/braslavskii_pautina_laigasha.zip 364 ./Браславский Дмитрий 368 ./Иванова Вероника/Ivanova -2.zip 376 ./Иванова Вероника/Ivanova_Veronika_Pravo_uchit(I_majatnik_kachnulsja-4)[1].fb2.zip 432 ./Иванова Вероника/Ivanova -1.zip 368 ./Иванова Вероника/Ivanova -3.zip 1548 ./Иванова Вероника 156 ./Де Ченси Джон/Замок3.zip 152 ./Де Ченси Джон/Замок2.zip 156 ./Де Ченси Джон/Замок1.zip 468 ./Де Ченси Джон 436 ./Малицкий Сергей/Malitzkij_Missija_dlja_chuzhezemtza(Arban_Saesh-1).fb2.zip 468 ./Малицкий Сергей/Malitzkij_Kameshek_v_zhernovah(Arban_Saesh-3).fb2.zip 492 ./Малицкий Сергей/Malitzkij_Otschet_tenej(Arban_Saesh-2).fb2.zip 1400 ./Малицкий Сергей 320 ./Уланов Андрей/ulanov_andrei_kolduny_i_kapusta.rtf.zip 4 ./Уланов Андрей/descript.ion 292 ./Уланов Андрей/ulanov_andrei_kolduny_i_kapusta.zip 316 ./Уланов Андрей/ulanov_andrei_na_vseh_hvatit.fb2.zip 272 ./Уланов Андрей/Ulanov_Princessa_dlja_serzhanta.zip 316 ./Уланов Андрей/Ulanov_Dodge_po_imeni_Arizona.zip 1524 ./Уланов Андрей 424 ./Королев Павел/Kornev_Skolzkij(Prigranichje-2).fb2.zip 360 ./Королев Павел/Kornev_Led.zip 788 ./Королев Павел 252 ./Мусаниф Сергей/Musanif_Imperskie_voiny.fb2.zip 256 ./Мусаниф Сергей/Musanif_Imperskii_gambit.fb2.zip 240 ./Мусаниф Сергей/Musanif_Imperskie_tancy.fb2.zip 752 ./Мусаниф Сергей 344 ./Ip-tables.zip 320 ./Зорич Александр/Пути Звезднорожденных/Пути Звезднорожденных-1.zip 328 ./Зорич Александр/Пути Звезднорожденных/Пути Звезднорожденных-3.zip 320 ./Зорич Александр/Пути Звезднорожденных/Пути Звезднорожденных-2.zip 972 ./Зорич Александр/Пути Звезднорожденных
Как видите в именах архивов есть и пробелы и различные символы.
Но это конечно фигня - мона и в цикл загнать по всем каталогам - тока эта команда дает странный результат
alex@hc-deb-al:~/Desktop/Гудкайнд Терри$ find -iname "*.zip" -exec unzip {} \;
Archive: ./Шестое правило волшебника.zip
inflating: ��ԫ� ���Неактивен
такс - обнаружил ограничение на размер сообщения - продолжаю
Но это конечно фигня - мона и в цикл загнать по всем каталогам - тока эта команда дает странный результат
[code]alex@hc-deb-al:~/Desktop/Гудкайнд Терри$ find -iname "*.zip" -exec unzip {} \;
Archive: ./Шестое правило волшебника.zip
inflating: ��ԫ� ���
Отредактированно alex2ndr (20-06-2008 10:45:17)
Неактивен
Нет - это не ограничение на размер сообщения - это форум не хочет воспроизводить те самые иероглифы в которые превратились имена файлов
Тогда раскажу на словах - при распаковке имена файлов из архива преобретают вид иероглифов(ромю\биков со знаками вопроса) - и не исправляються при последующем конвертировании, пробовал как cp1251 так и cp866 - результат одинаково нечитаем.
Ну до упаковки понятно я не дошел
Мне кажется что всетаки придется переводить в транслит - причем при распаковке сначала брать имя архива - потому что получившееся имя файла нечитаемо и непереводимо наверно - только хочется сохранить названия каталогов по русски
Постараюсь найти возможность выложить куда-нить несколько каталогов - чтобы можно было протестить скрипт
Всем спасибо за ответы
Неактивен
Вот вам заготовочка для начала:
find ./ | while read fname; do echo "$fname -> `echo $fname | iconv -fkoi8-r -tutf8`" ; done
Вы хотите перекодировать содержимое или имена файлов тоже? А имена каталогов?
PS: Только кодировки поменяйте в вызове iconv на нужные.
Неактивен
Вот скрипт, который перекодирует имена файлов и каталогов. Считается, что исходная структура в ./in, а результат он кладет в ./out.
Пробуйте. Если оно у вас заработает, то можно будет приступить к перепаковке архивов.
#!/bin/sh
find ./in/ -type f | while read fn; do
newfn=`echo $fn | iconv -fkoi8-r -tutf8 | sed 's/^\.\/in/\.\/out/'`
dirname=`dirname "$newfn"`
[ -d "$dirname" ] || mkdir -p "$dirname"
cp "$fn" "$newfn"
doneНеактивен
Wall говорит:
Вот скрипт, который перекодирует имена файлов и каталогов. Считается, что исходная структура в ./in, а результат он кладет в ./out.
Пробуйте. Если оно у вас заработает, то можно будет приступить к перепаковке архивов.
Попробовал с различными кодировками (iconv - l выдал огромный список - чтобы весь попробовать надо еще один скрипт писать - проверил самые вероятные - koi8-r, CP1251, CP866, WINDOWS-1251) - имена папок и архивов превратились в крякозяблики - содержимое архивов осталось прежним. Если это содержимое распаковать то при конвертации одни кракозяблики на другие меняються.
Имена каталогов хочу оставить на русском - переконвертировать (или написать в транслите) надо только имена файлов
Спасибо за участие - но боюсь данное решение не совсем верное - мне кажется что имя архива было конвертировано еще при переносе на таблетку - ведь в fstab стоит опция utf8 (как я понимаю это эквивалент того что стоит в моем fstab - nls=utf8), т. е. имена архивов уже в utf8 - но вот содержимое архивов попрежнему в непонятном формате (оно же не конвертировалось при переносе)- я сталкивался с таким когда переносил архивы созданные в linux по самбе на винду (монтировал виндовую папку в линух с опцией iocharset=koi8-r) - имя архива нормальное - а содержимое кракозябликами. Если мое предположение неверно - поправьте меня.
Залил несколько папок на Ifolder - http://ifolder.ru/7058757
желающие могут посмотреть - всего файлов которых нужно поправить там 8, и 6 таких, которых править не надо - постарался как можно более полно представить различные случаи для тестирования скрипта - я всетаки надеюсь написать скрипт который будет работать только с неправильными файлами
.
Всем еще раз спасибо
Отредактированно alex2ndr (21-06-2008 07:42:32)
Неактивен
Если вам только архивы распаковать, переименовать файлы в utf8 и запаковать обратно, то скрипт будет ненамного сложнее.
Ваш архив я прочитать не могу, мой unzip его не берет. Если запакуете во что-то более переносимое, то могу глянуть и наваять то, что вы хотите, если, конечно, я правильно вас понял.
Неактивен
закинул в чем то более переносимом
- http://ifolder.ru/7060446 
а предыдущий архив был в 7z - у меня берет так -
7z x primer.7z
Отредактированно alex2ndr (21-06-2008 10:03:32)
Неактивен
Wall говорит:
Если вам только архивы распаковать, переименовать файлы в utf8 и запаковать обратно, то скрипт будет ненамного сложнее.
У Вас возможно и ненамного - а у меня получилось вот так -
#!/bin/sh
#
# Script for convert file's names
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# Ищем файлы в каталоге ./in/
find ./in/ -type f | while read file_name; do
# повторяем структуру каталогов в ./out/
dir_name=`dirname "$file_name"`
new_dir_name=`dirname "$file_name" | sed 's/^\.\/in/\.\/out/'`
[ -d "$new_dir_name" ] || mkdir -p "$new_dir_name"
# запоминаем чистое имя файла - а заодно заменим пробелы на _
new_file_name=`echo "${file_name##"$dir_name/"}" | sed 's/ /_/g'`
# а эта переменная содержит имя файла которое ему нужно присвоить после распаковки - см ниже
new_file_name_txt=`echo "${file_name##"$dir_name/"}" | sed 's/ /_/g' | sed 's/\.zip/\.txt/'`
# Копируем файлы из ./in/ в ./out/
cp "$file_name" "$new_dir_name"
# Ищем только файлы содержащие русские буквы
if [ -n "`find "$new_dir_name" -maxdepth 1 -type f -iname "*[а-я]*"`" ]
then
# Так как я не смог договориться с unzip то ищу файлы содержащие пробелы
temp_file_name_0=`find "$new_dir_name" -maxdepth 1 -type f -iname "* *"`
if [ -n "$temp_file_name_0" ]
then
# А затем заменяю в них пробелы на _
temp_file_name_1="$new_dir_name/$new_file_name"
mv "$temp_file_name_0" "$temp_file_name_1"
# Затем я их распаковываю - вот тут у меня основная проблема - я не знаю как
# их сразу после этого переименовать в $new_file_name_txt - подскажите кто знает
unzip "$temp_file_name_1" -d "$new_dir_name"
# а потом удалаю первоначальные архивы
rm "$temp_file_name_1"
else
# Здесь тоже самое только для файлов без пробелов
temp_file_name_2=`find "$new_dir_name" -maxdepth 1 -type f -name "$new_file_name"`
unzip "$temp_file_name_2" -d "$new_dir_name"
rm "$temp_file_name_2"
fi
fi
done
exit 0прошу сразу ногами не пинать - скриптер из меня неважный как я уже говорил. Основная проблема описана в коментариях - повторю просто - не знаю как переименовать файл со стандартного ввода (или еще как - я его потом не могу в каталоге найти так как у него имя кракозябликами ), в Вашем скрипте используется iconv что не совсем то что я хочу (точнее не получается у меня им воспользоваться, да и хочу я транслитерацию - но как это сделать не знаю тем более)
2 Wall
В любом случае спасибо за Ваш скрипт - он послужил мне основой
Отредактированно alex2ndr (21-06-2008 10:39:38)
Неактивен
dik@storm:~/$ ls | enca
Universal transformation format 8 bits; UTF-8
Doubly-encoded to UTF-8 from maccyr
dik@storm:~/$ unzip ДИК\ САЙМОН\ –\ 1.zip
Archive: ДИК САЙМОН – 1.zip
inflating: ����� - 1.txt
dik@storm:~/$ ls *.txt | enca
Unrecognized encoding
Можно сделать проще - называть txt после извлечения из архива - именем архива.
unzip "$temp_file_name_1" -d "$new_dir_name" txtname = `cd "$new_dir_name"; ls -t *.txt | sed -n '1p' zipname = `echo "$temp_file_name_1" | sed 's/.zip/.txt/'` mv "$txtname" "$zipname"
Неактивен
Как-то все у вас сложно ![]()
Ответьте мне на 2 вопроса:
- В архивах у вас по одному файлу?
- расширение у файлов .txt ?
Если это так, то все можно сделать гораздо проще.
Неактивен
- В архивах у вас по одному файлу?
в подавляющем большинстве случаев по одному - книги то я по одной читал
- расширение у файлов .txt ?
В больщинстве да - но я думаю найдется некоторое количество с расширением fb2
Неактивен
Вот короткий вариант того, что делает ваш скрипт, за исключением замены пробелов на подчеркивания.
Ну, по крайней мере как я его понял ![]()
cp -r in out find ./out/ -type f -iname "*[а-я]*.zip" | while read fn ; do unzip -p "$fn" > "`echo $fn | sed 's/\.zip$/.txt/'`" ;done
Неактивен
dik говорит:
Можно сделать проще - называть txt после извлечения из архива - именем архива.
я так уже пробовал - он потом файл с таким название не может найти и ругается - как я понял мона тока через конвеер(мне так кажется) -вот такая ошибка выдается для каждого из файлов -
mv: невозможно выполнить stat для `\304ի\324\341 \241\341 \253ի\324\241\277\254\3412.txt': No such file or directory
Wall говорит:
от короткий вариант того, что делает ваш скрипт, за исключением замены пробелов на подчеркивания.
спасибо конечно - только я не смог добиться от него такой же функциональности(копируется нормально - но вот что там с распаковкой неизвестно - архивы остались архивами) - а отлаживать такое я не умею (в моем когда не получается я через echo вывожу значения переменных и смотрю какие они) - и насчет размера все верно - мой как раз на присвоение\описание всех этих переменных больше
Неактивен
Вы где его запускаете? У моего unzip-а есть ключ -p - распаковывать на stdout. Я им и попользовался. А архивы я оставляю нетронутыми, я только рядом распакованый файл кладу с именем архива и расширением .txt.
PS: Ваш скрипт у меня тоже не работает, кстати. Ругается так: "... Нет такого файла или каталога", "unzip: cannot find or open ./out/..."rm: невозможно удалить ...".
Неактивен
а там надо два каталога создать - ./in и ./out (Ваша идея кстати) - я не стал писать проверку на их наличие - как то не подумал что у других их может не быть.
А ключ -p и у моего unzip есть
Неактивен
Вот вам 'развернутый вариант', но он короче не на присвоение и описание переменных - у него логика в три строчки ![]()
cp -r in out
find ./out/ -type f -iname '*[а-я]*.zip' | while read fn ; do
newfn="`echo $fn | sed -e 's/\.zip$/.txt/'`"
unzip -p "$fn" > "$newfn"
doneТеперь понятно?
Чтобы не быть голословным вот результат:
$ rm -rf out $ find ./in/ ./in/ ./in/Авраменко Олег ./in/Авраменко Олег/Avramenko_Vse_grani_mira.zip ./in/Авраменко Олег/Avramenko_Grani_nizhnego_mira.zip ./in/Дашков Андрей ./in/Дашков Андрей/ВОЙНЫ НЕКРОМАНТОВ.zip ./in/Злотников Роман ./in/Злотников Роман/Вечный ./in/Злотников Роман/Вечный/Вечный2.zip ./in/Злотников Роман/Вечный/Вечный3.zip ./in/Злотников Роман/Вечный/Вечный1.zip ./in/Злотников Роман/Вечный/Вечный4.zip ./in/Злотников Роман/Арвендэйл ./in/Злотников Роман/Арвендэйл/Arvendejl1.zip ./in/Злотников Роман/Арвендэйл/Arvendejl2.zip ./in/Злотников Роман/Охота на охотника ./in/Злотников Роман/Охота на охотника/Охота на охотника2.zip ./in/Злотников Роман/Охота на охотника/Охота на охотника1.zip ./in/Ахманов Михаил ./in/Ахманов Михаил/Ahmanov_Skifi_pirujut_na_zakate-1.zip ./in/Ахманов Михаил/Ahmanov_Strannik_prishedshii_izdaleka-2.zip ./in/Ахманов Михаил/ДИК САЙМОН – 1.zip $ sh ../recode2 $ find ./out/ ./out/ ./out/Авраменко Олег ./out/Авраменко Олег/Avramenko_Vse_grani_mira.zip ./out/Авраменко Олег/Avramenko_Grani_nizhnego_mira.zip ./out/Дашков Андрей ./out/Дашков Андрей/ВОЙНЫ НЕКРОМАНТОВ.zip ./out/Дашков Андрей/ВОЙНЫ НЕКРОМАНТОВ.txt ./out/Злотников Роман ./out/Злотников Роман/Вечный ./out/Злотников Роман/Вечный/Вечный2.zip ./out/Злотников Роман/Вечный/Вечный4.txt ./out/Злотников Роман/Вечный/Вечный2.txt ./out/Злотников Роман/Вечный/Вечный3.txt ./out/Злотников Роман/Вечный/Вечный3.zip ./out/Злотников Роман/Вечный/Вечный1.zip ./out/Злотников Роман/Вечный/Вечный1.txt ./out/Злотников Роман/Вечный/Вечный4.zip ./out/Злотников Роман/Арвендэйл ./out/Злотников Роман/Арвендэйл/Arvendejl1.zip ./out/Злотников Роман/Арвендэйл/Arvendejl2.zip ./out/Злотников Роман/Охота на охотника ./out/Злотников Роман/Охота на охотника/Охота на охотника2.zip ./out/Злотников Роман/Охота на охотника/Охота на охотника1.txt ./out/Злотников Роман/Охота на охотника/Охота на охотника1.zip ./out/Злотников Роман/Охота на охотника/Охота на охотника2.txt ./out/Ахманов Михаил ./out/Ахманов Михаил/Ahmanov_Skifi_pirujut_na_zakate-1.zip ./out/Ахманов Михаил/Ahmanov_Strannik_prishedshii_izdaleka-2.zip ./out/Ахманов Михаил/ДИК САЙМОН – 1.txt ./out/Ахманов Михаил/ДИК САЙМОН – 1.zip
Неактивен
2Wall
Да - Вы правы - разобрался - работает такой скрипт вполне - у меня там была проблема с -iname '*[а-я]*.zip - русские символы в кракозяблики почему то обращались при записи файла - страно это - в остальных файлах такого не было. Но если эту часть выкинуть то ввсе вполне работает(хотя и англицкие тож распаковывает - ну да ладно)
Большое Вам спасибо за то что обратили внимание на uname -p - в моем скрипте я заменил строчку
unzip "$temp_file_name_1" -d "$new_dir_name"
на
unzip -p "$temp_file_name_1" > "$new_dir_name/$new_file_name_txt"
и получил то что надо - имена файлов нормально отобразились - только плиз скажите как теперь это запаковать все в zip - понимаю что осталось приписать что нить туда в конвеер - только вот что разбираться сил не осталось (весь день сегодня это кодю и читаю Advanced Bash-Scripting Guide - я ж в скриптах совсем новичок)
PS Оптимизацией завтра займусь - действительно можно выкинуть кучу всего
Отредактированно alex2ndr (21-06-2008 13:26:15)
Неактивен
alex2ndr говорит:
а там надо два каталога создать - ./in и ./out (Ваша идея кстати) - я не стал писать проверку на их наличие - как то не подумал что у других их может не быть.
А это что не проверка?
[ -d "$new_dir_name" ] || mkdir -p "$new_dir_name"
А ключ -p и у моего unzip есть
Тогда смотрите развернутый вариант моего скрипта и говорите что не работает.
PS: Не знаю что я делаю не так, но после создания out ваш скрипт не ругается, но ничего и не делает. Его результат - копия in в out.
Неактивен