最近、ファイルの TOC を印刷するコマンドを実行しましたpdf
。
mutool show file.pdf outline
epub
上記のフォーマットと同様に、使い方が簡単で、優れた結果が得られるコマンドをフォーマットに使用したいと思いますpdf
。
そういうのってあるんですか?
答え1
.epub
ファイルは、 XHTML と CSS およびその他のファイル (画像、さまざまなメタデータ ファイル、および目次を含む.zip
XML ファイルなど) を含むファイルです。toc.ncx
次のスクリプトは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 のファイル名の後に を出力し:
、次の行の各章のタイトルを 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
最初のエラー行は からのものでunzip
、2 番目の行は からのものですxml2
。 また、不適切にフォーマットされたファイルxml2
など、検出されたその他のエラーについても警告します。toc.ncx
エラー メッセージは stderr にありますが、本のファイル名は stdout にあることに注意してください。
xml2
Debian、Ubuntu、その他の Debian 派生版、そしておそらく他のほとんどの Linux ディストリビューション向けにパッケージ化済みで提供されています。
このような単純なタスク (つまりsed
、、、、などで使用するために XML を行指向形式に変換するだけの場合) では、よりも の方がシンプルで使いやすくなっています。awk
cut
grep
xml2
xmlstarlet
ちなみに、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 で、toc.ncx
zip コンテナの最上位に NCX ドキュメントの名前が付けられていることを前提としています。1 つのフォルダにある 223 個の epub のうち、この前提を満たすのは 5 個だけです。これらの epub には、古いリーダー システムとの互換性のためだけに が含まれています。 はtoc.ncx
必須のファイルではありませんMETA-INF/content.xml
。必須のファイルは です。これには、epub の他のすべての要素へのポインタが含まれます。これにより、bash によるスクリプト作成が少し複雑になりますが、可能です。以下は、(content.xml によってポイントされる) opf ファイルからタイトルと著者を取得するスクリプトです。
#! /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 ファイルを見つけるためにもう 1 歩進むと、少しトリッキーになります。xml2 を使用して各タグと属性ごとに 1 行を生成すると、ここでは不利になります。属性が に等しいhref
属性の値が必要です。少しずるをして、元の項目がすべて 1 行にあることを期待し、grep を使用してそのフラグメントだけを抽出し、それを xml2 で処理して href 値を取得します。media-type
application/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 個すべてに TOC が表示されます (ただし、ncx にタイトルがないものもあります)。