LINUX.ORG.RU

Переименование overМного fb2.

 


0

1

После пополнения библиографии появилась проблема - Как переименовать?
В google дидактического материалу не нашёл. Надеюсь на тебя и уповаю всемогущий лор.

Для наглядности масштаб бедствия (с оверхедом).



Последнее исправление: windusjatnik (всего исправлений: 1)

переименовать каким образом?
почему просто не использовать каталогизатор типа myrulib?

e1nste1n ★★★★★
()
find -name '*.fb2' | sed 's/.../mv \"\0\" \"...\"/' | sh

Я обычно делаю как-то так. Можно ещё через скрипт аналогичный translate.ru прогнать.

mix_mix ★★★★★
()

адрес сайта можно тупо вырезать, переводить из транслита ябы не рекомендовал - читалки все еще бывают корявые

Deleted
()
Ответ на: комментарий от e1nste1n

переименовать каким образом?

Надеялся на что-то вроде скрипта который выдернет названия из <title>.

почему просто не использовать каталогизатор типа myrulib?

Так сначала хочу почистить от это самого овехеда, где-то 25% отсею.
Каталогизаторами не пользуюсь.

windusjatnik
() автор топика
Ответ на: комментарий от windusjatnik

Перед тем как что-то подсовывать через пайп sh, нужно первым делом смотреть что же конвеер там такого нагенерировал, то есть пускать без него. Очевидно, sed выплёвывает какую-то фигню.

mix_mix ★★★★★
()
Ответ на: комментарий от mix_mix

Багрепорт нумбер два:)

...
mv "./L" "..."ondon_Mamont_Tomasa_Stivensa.33858.fb2
mv "./L" "..."ondon_Zolotoe_dno.151062.fb2
mv "./L" "..."ondon_Neozhidannoe.151033.fb2
mv "./L" "..."ondon_Prisheltsyi_iz_Solnechnoy_Stranyi.33906.fb2
mv "./L" "..."ondon_Stsapali.69511.fb2
mv "./L" "..."ondon_Oskolok_tretichnoy_epohi.33888.fb2
mv "./L" "..."ondon_Sila_silnyih.33922.fb2
...

windusjatnik
() автор топика
Ответ на: комментарий от mix_mix

я же тебе пример команды привёл, кишки в sed, я надеялся, сам напишешь.

Ну, я пошёл другим путём. Сначала всё в utf8.

for i in *; do iconv -f WINDOWS-1251 -t UTF-8 "$i" >tmp; mv tmp "$i"; done
Потом заклинание!
perl -wlne'/title>([^<]+)/i&&rename$ARGV,"$1.fb2"' * 
На выходе почти профит! Из 205 файлов всего 6 неправильно переименовались. Автора не зацепил, как-то так.
[~/Downloads/London][HPCompaq]%[test]=> ls *fb2 |tail                                    
Человек со Шрамом.fb2
Через стремнины к Клондайку.fb2
Черты литературного развития.fb2
Что значит для меня жизнь.fb2
Чун А-Чун.fb2
Шериф Коны.fb2
Шутка Порпортука.fb2
Шутники с Нью-Гиббона.fb2
Эти кости встанут снова.fb2
Язычник.fb2
  

Осталось rename аффтара добавить, но это уже мелочь.

Всем спасибо! Решено.

windusjatnik
() автор топика
Последнее исправление: windusjatnik (всего исправлений: 2)
Ответ на: комментарий от mix_mix

Не совсем. Но я уже подкорректировал. Здесь же только примеры,
до остального сами дойдут, я надеюсь:)

windusjatnik
() автор топика
Ответ на: комментарий от e1nste1n

почему просто не использовать каталогизатор типа myrulib?

Так и не нашёл бесплатного каталогизатора, который бы работал в рамках строннего каталога с книгами и переименовывал файлы или на месте или по моей маске. Либо тянут к себе, либо переименовывают как хотят, либо и то, и другое вместе. По хорошему, надо написать тупо скрипт на Питоне, там будет десятка полтора строк всего, но всё лениво ковыряться...

Вот myrulib не умеет переименовывать. А использовать библиотеку нужно на разных девайсах, с синхронизацией структуры, в т.ч. из под Android.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

держи друг

#!/usr/bin/env python3

import re
import os
from lxml import etree

def getFirst(node, key, ns):
  key = '{0}{1}'.format(ns, key)
  lst =  list(node.iter(key))
  return lst[0] if lst else None

def getText(node, key, ns):
  node = getFirst(node, key, ns)
  return node.text if node is not None else ''

def getNamespace(tag):
  m = re.match('\{.*\}', tag)
  return m.group(0) if m else ''

def parse(fname):
  print(fname)
  root = etree.XML(open(fname, 'rb').read())
  ns = getNamespace(root.tag)
  try:
    ti = getFirst(root, 'title-info', ns)

    bt = getText(ti, 'book-title', ns)

    author = getFirst(ti, 'author', ns)
    fn = getText(author, 'first-name', ns)
    ln = getText(author, 'last-name', ns)

    return '{0} {1} - {2}.fb2'.format(fn, ln, bt)
  except:
    return fname

for dname, dnames, fnames in os.walk('from'):
  for fname in fnames:
    if fname[-4:].lower() == '.fb2':
      nfname = parse(os.path.join(dname, fname))
      print('{0} -> "{1}"'.format(fname, nfname))

anonymous
()
Ответ на: комментарий от KRoN73

Тоже не нравилось это в calibre в своё время, но смирился со временем.

HunOL ★★★★
()
Ответ на: комментарий от anonymous
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# источник/назначение
dname_src = 'src'
dname_dst = 'dst'

# формат
fmt = '{0} {1} - {2}.fb2'

# аргументы
args = [
  ['title-info', 'author', 'first-name'],
  ['title-info', 'author', 'last-name'],
  ['title-info', 'book-title'],
]

# режим работы
mode = 'emulation' # только сообщения
#mode = 'copyFile'  # скопировать файлы
#mode = 'moveFile'  # переместить файлы

###

import re
import os
import shutil
from xml.dom import minidom

def getFirst(node, key):
  lst = node.getElementsByTagName(key)
  return lst[0] if lst else None

def getText(node, key, ns):
  node = getFirst(node, key, ns)
  return node.text if node is not None else ''

def solveArg(node, args):
  path = []
  for arg in args:
    path.append(arg)
    node = getFirst(node, arg)
    assert node, "Can't find node '{0}'".format('/'.join(path))
  return node.firstChild.data

def parse(fname, fmt, args):
  root = minidom.parse(fname)
  assert root, "Can't open file '{0}'".format(fname)
  args = [solveArg(root, a) for a in args]
  fname = fmt.format(*args)
  return fname

def makeDirs(dname):
  if os.path.exists(dname) == False:
    os.makedirs(dname)

def modifyFile_emulation(src, dst):
    print('{0} -> {1}'.format(src, dst))

def modifyFile_copyFile(src, dst):
  makeDirs(os.path.dirname(dst))
  shutil.copyfile(src, dst)
  modifyFile_emulation(src, dst)

def modifyFile_moveFile(src, dst):
  makeDirs(os.path.dirname(dst))
  shutil.move(src, dst)
  modifyFile_emulation(src, dst)

modifyFile = {
  "emulation": modifyFile_emulation,
  "copyFile":  modifyFile_copyFile,
  "moveFile":  modifyFile_moveFile,
}[mode]

for dname, dnames, fnames in os.walk(dname_src):
  for fname in fnames:
    if fname[-4:].lower() == '.fb2':
      try:
        fname_src = os.path.join(dname, fname)
        fname_dst = parse(fname_src, fmt, args)
        dst = dname_dst + dname[len(dname_src):]
        dst = os.path.join(dst, fname_dst)
        modifyFile(fname_src, dst)
      except Exception as e:
        print('{0}: {1}'.format(fname_src, e))
anonymous
()
Ответ на: комментарий от debugger

Вместо iconv хорошо пользовать enconv

Попрбовал определять кодировку системными утилитами, не понравился результат.
Решил брать из первой строки fb2. Файлы которые уже utf8 тупо убирал в /tmp

...........

# Переместить все файлы utf8 в папку utf8
for i in * ; do grep -L 'windows-1251\|Windows-1251' "$i"; done |xargs mv -t /tmp/utf8

# Перекодировать все файлы из 1251 в utf8
for i in *; do iconv -f WINDOWS-1251 -t UTF-8 "$i" >tmp; mv tmp "$i"; done
# Замена в файлах <title> windows-1251 на utf-8 ! && zsh для zsh
grep -L 'utf-8\|UTF-8' * | xargs |sh| for i in *; do sed 's/windows-1251/utf-8/g' "$i" >tmp; mv tmp "$i"; done && zsh

mv /tmp/utf8/* ./

...........
windusjatnik
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.