.epub
arquivos são .zip
arquivos contendo XHTML e CSS e alguns outros arquivos (incluindo imagens, vários arquivos de metadados e talvez um arquivo XML chamado toc.ncx
contendo o índice).
O script a seguir usa unzip -p
para extrair toc.ncx
para stdout, canalizá-lo pelo comando xml2 e, em seguida, sed
para extrair apenas o texto de cada título de capítulo.
Leva um ou mais argumentos de nome de arquivo na linha de comando.
#! /bin/sh
# This script needs InfoZIP's unzip program
# and the xml2 tool from http://ofb.net/~egnor/xml2/
# and sed, of course.
for f in "$@" ; do
echo "$f:"
unzip -p "$f" toc.ncx |
xml2 |
sed -n -e 's:^/ncx/navMap/navPoint/navLabel/text=: :p'
echo
done
Ele exibe o nome do arquivo do epub seguido por um :
, em seguida, recua cada título do capítulo por dois espaços nas linhas a seguir. Por exemplo:
book.epub:
Chapter One
Chapter Two
Chapter Three
Chapter Four
Chapter Five
book2.epub:
Chapter One
Chapter Two
Chapter Three
Chapter Four
Chapter Five
Se um arquivo epub não contiver um toc.ncx
, você verá uma saída como essa para o livro em questão:
book3.epub:
caution: filename not matched: toc.ncx
error: Extra content at the end of the document
A primeira linha de erro é de unzip
, a segunda de xml2
. xml2
também avisará sobre outros erros encontrados - por exemplo, um arquivo toc.ncx
incorretamente formatado.
Observe que as mensagens de erro estão no stderr, enquanto o nome do arquivo do livro ainda está no stdout.
xml2
está disponível pré-empacotado para Debian, Ubuntu e outros derivados da Debian, e provavelmente a maioria das outras distribuições Linux também.
Para tarefas simples como essa (ou seja, onde você deseja converter XML em um formato orientado a linha para uso com sed
, awk
, cut
, grep
, etc), xml2
é mais simples e mais fácil de usar do que xmlstarlet
.
BTW, se você quiser imprimir o título do epub também, altere o script sed
para:
sed -n -e 's:^/ncx/navMap/navPoint/navLabel/text=: :p
s!^/ncx/docTitle/text=! Title: !p'
ou substitua-o por um script awk
:
awk -F= '/(navLabel|docTitle)\/text/ {print $2}'