epubファイルを抽出するディレクトリ

epubファイルを抽出するディレクトリ

最近ファイルディレクトリを印刷するコマンドをクリックしましたpdf

mutool show file.pdf outline

epub上記の形式と同様に、使い方が簡単で良い結果を出すコマンドを使用したいと思いますpdf

そんなことありますか?

答え1

.epubファイルは、.zipXHTMLおよびCSSだけでなく、画像、さまざまなメタデータファイル、およびインクルードディレクトリと呼ばれるtoc.ncxXMLファイルを含む他のファイルを含むファイルです。

次のスクリプトはstdoutにunzip -p抽出しtoc.ncxてパイプするために使用されます。XML2コマンドを実行し、sed各章のタイトルのテキストのみを抽出します。

コマンドラインで1つ以上のファイル名引数を受け入れます。

#! /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というファイル名とそのあとにepubが出力され:、次の行で各章タイトルを空白2つにインデントします。たとえば、

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

最初のエラー行はから出て、unzip2番目のエラー行はから来ますxml2。また、間違った形式のファイルなど、見つかったxml2他のエラーについても警告します。toc.ncx

エラーメッセージはstderrにありますが、本のファイル名はまだstdoutにあります。

xml2Debian、Ubuntu、およびその他のDebian派生製品は、他のほとんどのLinuxディストリビューション用に事前パッケージ化することができます。

sedこのような単純な操作の場合(つまり、、、awkなどcutで使用するためにXMLを行ベースの形式に変換したい場合grep)。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結果の順序を確認するために2回解析します。これにより、スプレッドシートのインポートに適したタブで区切られた3列ファイル(2つの前髪の間のsed行のタブ)が作成されます。

ncxファイルをもう一度探すのは少し面倒です。なぜなら、xml2を使用して各タグと属性の行を生成することは私たちにとって不利に働くからです。href属性と同じ属性の値が必要です。ちょっとした詐欺を使って、元のアイテムがすべて1行にあることを望み、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にヘッダーがありませんが)。

関連情報