epub 파일의 TOC 추출

epub 파일의 TOC 추출

최근에 파일의 TOC를 인쇄하는 명령을 쳤습니다 pdf.

mutool show file.pdf outline

epub위의 형식과 유사한 사용법의 단순성과 좋은 결과를 가진 형식에 대한 명령을 사용하고 싶습니다 pdf.

그런 게 있나요?

답변1

.epub파일은 .zipXHTML 및 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의 파일 이름 뒤에 a가 오는 것을 출력하고 :, 다음 줄에서 각 장 제목을 두 개의 공백으로 들여씁니다. 예를 들어:

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, 두 번째 오류 줄은 에서 입니다 xml2. xml2또한 발견된 다른 오류(예: 부적절하게 형식화된 파일)에 대해서도 경고합니다 toc.ncx.

오류 메시지는 stderr에 있지만 책의 파일 이름은 여전히 ​​stdout에 있습니다.

xml2Debian, Ubuntu 및 기타 debian 파생 제품과 아마도 대부분의 다른 Linux 배포판용으로 사전 패키지되어 제공됩니다.

sed이와 같은 간단한 작업(즉 , awk, cut, , 등과 함께 사용하기 위해 XML을 줄 기반 형식으로 변환하려는 경우 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

toc.ncx@cas가 제공한 답변이 어떤 경우에는 작동하지만 이는 zip 컨테이너의 최상위 수준에 이름이 지정된 NCX 문서가 있는 epub 버전 2.0을 가정한 것입니다 . 한 폴더에 223개의 epub이 있는데 5개만이 이 가정을 충족하며 이전 리더 시스템과의 호환성을 위해서만 포함되어 있습니다. 은 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에 제목이 부족하지만).

관련 정보