bash: пакетное переименование fb2

ВложениеРазмер
Иконка простого текстового файла ru2tr.txt956 байт
Иконка простого текстового файла fb2_renamer.sh_.txt1.03 КБ

Переименовываем fb2 в каталогах (плюс подкаталоги), попутно проверяя xml на правильность и перекодируя в UTF-8.
Использование: $ fb2_renamer.sh [-v] каталог [каталог ...]
Файлы переименовываются по шаблону "фамилия_имя_отчество_ник_название.fb2".

UPDATE: Ай-яй-яй. В прошлой версии было возможно зацикливание find'а. Поэтому складываем переименованные файлы в отдельный новый (под)каталог. Примерно так. Заодно раскидываем по подкаталогам с именем первого автора из title-info:

#!/bin/bash
verbose=0
if [ "$1" == "-v" ]; then
verbose=1
shift
fi
tmpdir=`mktemp -d "${1-.}/.FB2-XXXXXX"`
find "$@" -path "$tmpdir" -prune -o \( -type f -name "*.fb2" -print \) | \
while read i; do
tempfile=`mktemp -p "$tmpdir"`
tempfile2=`mktemp -p "$tmpdir"`
if XMLLINT_INDENT="" xmllint --encode UTF-8 --format "$i" 2>/dev/null >$tempfile; then
xml2 < $tempfile | grep title-info | grep '/author$\|=' > $tempfile2
author=`2csv < $tempfile2 author last-name first-name middle-name nickname | sed 's@,\+@_@g;s,_$,,;s,^$,_,' | head -n 1`
title=`2csv < $tempfile2 title-info book-title | head -n 1 | sed 's,["/],,g;s, \+,_,g;s,^_,,'`
name="${author}_${title}.fb2"
count=
newname="$name"
mkdir -p "$tmpdir/$author"
while [ -e "$tmpdir/$author/$newname" ]; do
count=$((count+1))
newname="${name%.fb2}${count}.fb2"
done
if [ $verbose -eq 1 ]; then
echo `basename "$i"` '->' "$newname"
fi
cp $tempfile "$tmpdir/$author/$newname"
rm "$i"
else
echo Error: `basename "$i"` 1>&2
fi
rm $tempfile $tempfile2
done

Perl-скрипт для преобразования русских имён в транслит:

#!/usr/bin/perl
use strict;
use locale;
use encoding 'UTF-8';
use open ':utf8';
use open ':std';
sub translit { ($_)=@_;
s/Сх/S\'h/; s/сх/s\'h/; s/СХ/S\'H/;
s/Ш/Sh/g; s/ш/sh/g;
s/Сцх/Sc\'h/; s/сцх/sc\'h/; s/СЦХ/SC\'H/;
s/Щ/Sch/g; s/щ/sch/g;
s/Цх/C\'h/; s/цх/c\'h/; s/ЦХ/C\'H/;
s/Ч/Ch/g; s/ч/ch/g;
s/Йа/J\'a/; s/йа/j\'a/; s/ЙА/J\'A/;
s/Я/Ja/g; s/я/ja/g;
s/Йо/J\'o/; s/йо/j\'o/; s/ЙО/J\'O/;
s/Ё/Jo/g; s/ё/jo/g;
s/Йу/J\'u/; s/йу/j\'u/; s/ЙУ/J\'U/;
s/Ю/Ju/g; s/ю/ju/g;
s/Э/E\'/g; s/э/e\'/g;
s/Е/E/g; s/е/e/g;
s/Зх/Z\'h/g; s/зх/z\'h/g; s/ЗХ/Z\'H/g;
s/Ж/Zh/g; s/ж/zh/g;
tr/
абвгдзийклмнопрстуфхцъыьАБВГДЗИЙКЛМНОПРСТУФХЦЪЫЬ/
abvgdzijklmnoprstufhc"y\'ABVGDZIJKLMNOPRSTUFHC"Y\'/;
s/[[:space:]]/_/g;
s/\p{Pd}/-/g;
s/…/.../g;
s/[^-.,?!()\[\]_'\da-z]//gi;
return $_;
}
while(<>) {
chomp;
print translit($_) . "\n";
}
exit(0);

Те же скрипты в прицепе:

Комментарии

Эээ....У меня не хватит опыта всё это повторить...
А есть какой-то GUI-вариант?..

magistral написал:
А есть какой-то GUI-вариант?..

Я не интересовался.
Мне удобнее CL.

2ground0 и остальным.

А нет ли у вас скрипта проверяющего парность < p> ... </p> и при ее отстутствии исправляющим fb2 файл.

Например, <p>  ... <p> ... </p> ->  <p> ... </p> .

Если такового нет, м.б. кто-нибудь напишет на perle. У меня хорошо написать не получилось. Думаю такой скрипт будет полезен не только мне.

1_абрам написал:
А нет ли у вас скрипта проверяющего парность < p> ... </p> и при ее отстутствии исправляющим fb2 файл.
Если такового нет, м.б. кто-нибудь напишет на perle. У меня хорошо написать не получилось. Думаю такой скрипт будет полезен не только мне.

Ещё один велосипед? xmllint все теги проверяет, <p> в том числе. И обнаруженные ошибки показывает, причём с номерами строк. (Ежели интегрировать в vim, вообще песня.)
А автоматическое исправление есть зло.

ground0 написал:
1_абрам написал:
А нет ли у вас скрипта проверяющего парность < p> ... </p> и при ее отстутствии исправляющим fb2 файл.
Если такового нет, м.б. кто-нибудь напишет на perle. У меня хорошо написать не получилось. Думаю такой скрипт будет полезен не только мне.

Ещё один велосипед? xmllint все теги проверяет, <p> в том числе. И обнаруженные ошибки показывает, причём с номерами строк. (Ежели интегрировать в vim, вообще песня.)
А автоматическое исправление есть зло.

Так кто мешает посмотреть результат автоматического исправлениия при помощи указанных вами средств. А непарные <p>...</p> - очень характерная ошибка, хотелось бы ее исправлять автоматически..

Есть ли аналог xmllint в windows? Хотелось бы его интегрировать в emeditor.

2SlaNT - спасибо за скрипт.

1_абрам написал:
Есть ли аналог xmllint в windows? Хотелось бы его интегрировать в emeditor.

Есть вроде сборка для windows (а чего сейчас нет?): http://www.zlatkovic.com/pub/libxml/ . Пакет libxml2. vim для windows можно взять на офсайте: http://www.vim.org/download.php#pc , - если что.
Схемы для FB2 можно взять на www.fictionbook.org, можно и без схем, просто как xml проверять.

1_абрам написал:
интегрировать в emeditor

Очередное проприетарное говноподелие с собственным макросным недоязычком?

Очередной линуксоид с марса?

Да linuxoid , хочу на марс , ищу спонсоров на 8*10^10$ , категорически не понимаю пользовательского нутряного хамства. Человек по своей инициантиве пишет , раздает исходники чтобы вы смогли их приспособить по надобности ,А быдло кричит : ХОчУ чтоб работало под моей программой х. Причем автор ищи прогу , покупай её или нарушай закон ,но подай на тарелочке сегодня . Одно слово - пишите сами или гоните бабки.

Под Pspad И MEDIT СКРИПТ ПОДГОНЯЕТСЯ ЗАМЕНОЙ ОДНОЙ СТРОЧКИ

find "$@" -type f -name "*.fb2" | \
заменяется на
echo "$1" | \

Далее см документацию редактора по подвешиванию скрипта

Для medit
homepage - http://mooedit.sourceforge.net/

manshtein написал:
medit

Очередное говноподелие с собственным макросным недоязычком? =1

Kiri написал:
manshtein написал:
medit

Очередное говноподелие с собственным макросным недоязычком? =1

Ну я писал про Emeditor - он получше будет чем medit.

Спасибо всем за ответы на мои вопросы.

Лучшее, что пока удалось сделать это интегрировать xmllint в PSPAD (путем компиляции текста - cntrlF9). Однако, не получается переход (по клику на сообщение об ошибке окошке log) на строчку с ошибкой в основном окне, чего бы очень хотелось. У кого нибудь это работает?

1_абрам написал:
Лучшее, что пока удалось сделать это интегрировать xmllint в PSPAD (путем компиляции текста - cntrlF9). Однако, не получается переход (по клику на сообщение об ошибке окошке log) на строчку с ошибкой в основном окне, чего бы очень хотелось. У кого нибудь это работает?

В виме работает: set errorformat=%f:%l:\ %m

ground0 написал:

В виме работает: set errorformat=%f:%l:\ %m

Да вим штука замечательная.

Изначально я его и попробовал (gvim 7.1) , но не показывает (зараза) UTF-8 файлов - зюки (с 1251 - все нормально).
Не смог пока эти зюки победить.

А ты его открой в нужной кодировке:
:e ++enc=utf8

не в тот пост написал

>В виме работает: set errorformat=%f:%l:\ %m

Да вим штука замечательная.

Изначально я его и попробовал (gvim 7.1) , но не показывает (зараза) UTF-8 файлов - зюки (с 1251 - все нормально).
Не смог пока эти зюки победить.

1_абрам написал:

Изначально я его и попробовал (gvim 7.1) , но не показывает (зараза) UTF-8 файлов - зюки (с 1251 - все нормально).
Не смог пока эти зюки победить.

Насколько мне помнится, надо просто сменить шрифт.
:help guifont

1_абрам написал:

Изначально я его и попробовал (gvim 7.1) , но не показывает (зараза) UTF-8 файлов - зюки (с 1251 - все нормально).
Не смог пока эти зюки победить.

Или же вим не определяет кодировку.
:e ++enc=utf8

set fileencodings=utf8,cp1251 в ~/.vimrc.

(Чё-то жоско глючит кэширование на либрусеке, сцуко.)

Цитата:
(Чё-то жоско глючит кэширование на либрусеке, сцуко.)
О, с этим бороться я давно приспособился. Если долго не выводится обновленная страница после сохранения, не нужно нажимать Сохранить повторно, а просто вернуться на исходную страницу до ввода сообщения и обновить ее. И в 99 из 100 - все ОК, сообщение сохранено. А для одного случая из 100 перед этой процедурой берем текст в буфер, чтобы не потерять. Для эффективной борьбы с такими багами (борьбы со стороны пользователя ;) очень полезно все время видеть трафик. Увидел короткую "вспышку" исходящего трафика - сообщение ушло, и можно смело обновлять страницу.

computers написал:
Цитата:
(Чё-то жоско глючит кэширование на либрусеке, сцуко.)
О, с этим бороться я давно приспособился. Если долго не выводится обновленная страница после сохранения, не нужно нажимать Сохранить повторно, а просто вернуться на исходную страницу до ввода сообщения и обновить ее. И в 99 из 100 - все ОК, сообщение сохранено. А для одного случая из 100 перед этой процедурой берем текст в буфер, чтобы не потерять. Для эффективной борьбы с такими багами (борьбы со стороны пользователя ;) очень полезно все время видеть трафик. Увидел короткую "вспышку" исходящего трафика - сообщение ушло, и можно смело обновлять страницу.

Я не совсем про это.
Иногда страницы отображаются не полностью, остаётся от всей темы, скажем, один заголовок. Дальше - обрыв хтмля. (Не до конца преобразуется вики-разметка, что ли?)
Обновление страницы здесь не очень помогает.

А "сохранять" два раза я не жму, ага, научился уже.

ground0 написал:
1_абрам написал:

Изначально я его и попробовал (gvim 7.1) , но не показывает (зараза) UTF-8 файлов - зюки (с 1251 - все нормально).
Не смог пока эти зюки победить.

Или же вим не определяет кодировку.
:e ++enc=utf8

set fileencodings=utf8,cp1251 в ~/.vimrc.

(Чё-то жоско глючит кэширование на либрусеке, сцуко.)

Спасибо получилось - нужно вставить в vimrc set encoding=utf-8.
А вот xmllint не заработало:
после компиляции сообщение:
!xmmlint --valid --nooout >D:\DOCUME~\Admin\LOCALS~1\Temp\VIeB0.tmp 2 >&1

В указанной директории файл VIeB0.tmp не создается.

За что на Python так ополчились ?

Ну наверное такое решение только для фанатов vim :)
Мой вариант проще :) http://lib.rus.ec/node/101686

В первом скрипте рекомендую дополнить команду, устанавливающую title, командой sed так: title=`2csv < $tempfile2 title-info book-title | head -n 1 | sed 's/^"\(.*\)"$/\1/'`
чтобы кавычки, которыми обрамляются сложные текстовые строки в csv (напрпример, содержащие запятую) правильно удалялись. Кажется, ru2tr не удаляет кавычки, не проверял, ибо транслит мне не нужен.

Ваш блог отличный, а за этот пост со скриптами особенное спасибо.

orivej написал:
Кажется, ru2tr не удаляет кавычки

Удаляет. Но если через него не пускать, не помешает, согласен. Вместе с другими спецсимволами, типа слэша.

orivej написал:
Ваш блог отличный, а за этот пост со скриптами особенное спасибо.

На здоровье.

ground0 написал:

Perl-скрипт для преобразования русских имён в транслит:

Вопрос: насколько этот транслит похож на Альдебарановский/Литресовский? А то мне тут понадобилось для fb2-file renamer-а, хочется чтобы близко к существующим было. (я на Перле пишу, но не перловкой, а как будто родным-любимым, только покалеченным, C пользуюсь - перловые идиомы ненавижу и рзбираться в них не хочу и не буду, ни-за-что, разве что за деньги)

pkn написал:
Вопрос: насколько этот транслит похож на Альдебарановский/Литресовский? А то мне тут понадобилось для fb2-file renamer-а, хочется чтобы близко к существующим было. (я на Перле пишу, но не перловкой, а как будто родным-любимым, только покалеченным, C пользуюсь - перловые идиомы ненавижу и рзбираться в них не хочу и не буду, ни-за-что, разве что за деньги)

Скрипт был утянут отсюда. Не знаю как с альдом/литресом, а на либрусековский не похож.
Вот ф-я на PHP из librusec.rar:
function translitcyr($cyr_str) {
$transtbl = array("Ґ"=>"G","Ё"=>"Yo","Є"=>"E","Ї"=>"Yi","І"=>"I",
   "і"=>"i","ґ"=>"g","ё"=>"yo","№"=>"N","є"=>"e",
   "ї"=>"yi","А"=>"A","Б"=>"B","В"=>"V","Г"=>"G",
   "Д"=>"D","Е"=>"E","Ж"=>"Zh","З"=>"Z","И"=>"I",
   "Й"=>"Y","К"=>"K","Л"=>"L","М"=>"M","Н"=>"N",
   "О"=>"O","П"=>"P","Р"=>"R","С"=>"S","Т"=>"T",
   "У"=>"U","Ф"=>"F","Х"=>"H","Ц"=>"Ts","Ч"=>"Ch",
   "Ш"=>"Sh","Щ"=>"Sch","Ъ"=>"","Ы"=>"Yi","Ь"=>"",
   "Э"=>"E","Ю"=>"Yu","Я"=>"Ya","а"=>"a","б"=>"b",
   "в"=>"v","г"=>"g","д"=>"d","е"=>"e","ж"=>"zh",
   "з"=>"z","и"=>"i","й"=>"y","к"=>"k","л"=>"l",
   "м"=>"m","н"=>"n","о"=>"o","п"=>"p","р"=>"r",
   "с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"h",
   "ц"=>"ts","ч"=>"ch","ш"=>"sh","щ"=>"sch","ъ"=>"",
   "ы"=>"yi","ь"=>"","э"=>"e","ю"=>"yu","я"=>"ya",
   " "=>'_', '"'=>'', "'"=>'',":"=>'', "("=>'_',")"=>'_',"["=>'_',"]"=>'_',"{"=>'_',"}"=>'_',
   'ў'=>'y', '…' => '.', '!'=>'','“'=>'','”'=>'', '`'=>'', '—'=>'-',
   '?'=>'',','=>'','\''=>'','«'=>'','»'=>'', '&'=>'_', '#' => 'N');
   return str_replace('__','_', strtr($cyr_str, $transtbl));
}

а ведь неверное преобразование =((

Крайний: ГОСТ 7.79:2000 "Система стандартов по информации, библиотечному и издательскому делу. Правила транслитерации кирилловского письма латинским алфавитом."

#!/usr/bin/python -O
# -*- coding: utf-8 -*-

_Translit = { # GOST 7.79-2000
        u"а":"a",   u"А":"A",
        u"б":"b",   u"Б":"B",
        u"в":"v",   u"В":"V",
        u"г":"g",   u"Г":"G",
        u"д":"d",   u"Д":"D",
        u"е":"e",   u"Е":"E",
        u"ё":"jo",  u"Ё":"Jo",
        u"ж":"zh",  u"Ж":"Zh",
        u"з":"z",   u"З":"Z",
        u"и":"i",   u"И":"I",
        u"й":"jj",  u"Й":"Jj",
        u"к":"k",   u"К":"K",
        u"л":"l",   u"Л":"L",
        u"м":"m",   u"М":"M",
        u"н":"n",   u"Н":"N",
        u"о":"o",   u"О":"O",
        u"п":"p",   u"П":"P",
        u"р":"r",   u"Р":"R",
        u"с":"s",   u"С":"S",
        u"т":"t",   u"Т":"T",
        u"у":"u",   u"У":"U",
        u"ф":"f",   u"Ф":"F",
        u"х":"kh",  u"Х":"Kh",
        u"ц":"c",   u"Ц":"C",
        u"ч":"ch",  u"Ч":"Ch",
        u"ш":"sh",  u"Ш":"Sh",
        u"щ":"shh", u"Щ":"Shh",
        u"ъ":"''",  u"Ъ":"''",
        u"ы":"y",   u"Ы":"Y",
        u"ь":"'",   u"Ь":"'",
        u"э":"eh",  u"Э":"Eh",
        u"ю":"ju",  u"Ю":"Ju",
        u"я":"ja",  u"Я":"Ja",
}
def translit(s): return ''.join([_Translit.get(c,c) for c in s])

Спасибо за скрипт.
В Ubuntu 10.10 для работы fb2_renamer.sh предварительно нужно установить пакет xml2.

X