提取 epub 檔案的目錄

提取 epub 檔案的目錄

最近我點擊了列印文件目錄的指令pdf

mutool show file.pdf outline

我想使用一個epub與上述格式類似的簡單用法和良好結果的命令pdf

有這樣的事嗎?

答案1

.epub文件是.zip包含 XHTML 和 CSS 以及其他一些文件(包括圖像、各種元資料文件,可能還有一個稱為toc.ncx包含目錄的 XML 文件)的文件。

以下腳本用於unzip -p提取toc.ncx到標準輸出,透過管道將其傳輸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 中缺少標題)

相關內容