提取 epub 文件的目录

提取 epub 文件的目录

最近我点击了打印文件目录的命令pdf

mutool show file.pdf outline

我想使用一个epub与上述格式类似的简单用法和良好结果的命令pdf

有这样的事吗?

答案1

.epub文件是.zip包含 XHTML 和 CSS 以及其他一些文件(包括图像、各种元数据文件,可能还有一个称为toc.ncx包含目录的 XML 文件)的文件。

以下脚本用于unzip -p提取toc.ncx到 stdout,并通过管道传输XML2命令,然后sed仅提取每个章节标题的文本。

它在命令行上接受一个或多个文件名参数。

#! /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

它输出 epub 的文件名,后跟:,然后在接下来的行中将每个章节标题缩进两个空格。例如:

book.epub:
  Chapter One
  Chapter Two
  Chapter Three
  Chapter Four
  Chapter Five

book2.epub:
  Chapter One
  Chapter Two
  Chapter Three
  Chapter Four
  Chapter Five

如果 epub 文件不包含toc.ncx,您将看到该特定书籍的如下输出:

book3.epub:
caution: filename not matched:  toc.ncx
error: Extra content at the end of the document

第一个错误行来自unzip,第二个错误行来自xml2xml2还将警告它发现的其他错误 - 例如格式不正确的toc.ncx文件。

请注意,错误消息位于 stderr 上,而本书的文件名仍位于 stdout 上。

xml2可以为 Debian、Ubuntu 和其他 debian 衍生品以及大多数其他 Linux 发行版预先打包。

对于像这样的简单任务(即您只想将 XML 转换为面向行的格式以便与sedawkcutgrep等一起使用),xml2xmlstarlet.

顺便说一句,如果您还想打印 epub 的标题,请将sed脚本更改为:

sed -n -e 's:^/ncx/navMap/navPoint/navLabel/text=:  :p
           s!^/ncx/docTitle/text=!  Title: !p'

或用脚本替换它awk

awk -F= '/(navLabel|docTitle)\/text/ {print $2}'

答案2

虽然 @cas 提供的答案在某些情况下有效,但它基于 epub 版本 2.0 的假设,并且 NCX 文档toc.ncx在 zip 容器的顶层命名。在我在一个文件夹中拥有的 223 个 epub 中,只有 5 个仍然满足这一假设 - 并且这些 epub 包含它只是为了与旧的阅读器系统兼容。这toc.ncx不是必需的文件 - 必需的文件是META-INF/content.xml.这将包含指向 epub 的所有其他元素的指针。这使得通过 bash 编写脚本有点复杂,但也是可能的。这是一个将从 opf 文件中提取标题和作者的脚本(通过 content.xml 指向):

#! /bin/sh

for f in "$@" ; do
    echo -n "$f""   "
    opf=$(unzip -p "$f" META-INF/container.xml | 
        xml2 | 
        sed -n -e 's:^/container/rootfiles/rootfile/@full-path=::p')
    unzip -p "$f" "$opf" |
        xml2 |
        sed -n -e 's!^/package/metadata/dc:title=!  !p' | tr  '
' ' '
    unzip -p "$f" "$opf" |
        xml2 |
        sed -n -e 's!^/package/metadata/dc:creator=!    !p' | tr  '
' ' '
    echo
done

是的,它解析opf两次,以确保结果的顺序 - 这会生成一个制表符分隔的 3 列文件(这些是两个刘海之间的 sed 行中的制表符),适合电子表格导入。

再一步查找 ncx 文件有点棘手,因为使用 xml2 为每个标签和属性生成一行对我们不利:我们需要属性等于 的属性href的值。我们可以作一点欺骗,希望原始项目全部在一行上,然后使用 grep 提取该片段,然后使用 xml2 处理它以获得 href 值。media-typeapplication/x-dtbncx+xml

由于这是一个相对 url,我们还需要从 opf 条目中提取路径部分。把它们放在一起,给我们:

#! /bin/sh

for f in "$@" ; do
    echo "$f""  "
    opf=$(unzip -p "$f" META-INF/container.xml | 
        xml2 | 
        sed -n -e 's:^/container/rootfiles/rootfile/@full-path=::p')
    ncx=$(unzip -p "$f" "$opf" |
        grep application/x-dtbncx+xml| 
        xml2 |
        sed -n -e 's!^/item/@href=!!p')
    opf_filename=${opf##*/}
    opf_path=${opf%$opf_filename}
    unzip -p "$f" ${opf_path}${ncx} |
        xml2 |
        sed -n -e 's:^/ncx/navMap/navPoint/navLabel/text=:  :p
                   s!^/ncx/docTitle/text=!Title: !p'
done

这仍然做出假设,最有力的是这些是 epub2 兼容文件,因此在某处包含 ncx 文件。 Epub3 文档使用不同的基于 HTML 的导航格式。即便如此,我确实获得了所有 223 个测试文件的目录(尽管有些在 ncx 中缺少标题)

相关内容