15

I would like to use a command line program to extract the title of a book (possibly also other metadata) from its epub file and return it as a string.

I am using Linux, but my guess is that the question makes sense in other environments, too.

I expected to easily find a clear and simple answer by searching the web. But apparently that is not the case, or I am still too ignorant to recognize answers.

The command could look like this

getbookinfo -m title myfile.epub

and would yield the title of the book found in the epub file.

10

Here's a quick bash script (with no error-checking whatsoever) to do what you want:

#!/bin/bash
#
if [ $# -lt 3 ]
then
   echo
   echo "Usage: minfo -m <meta-type> <epub-file>"
   echo
else
   fileloc=`unzip -l "$3" | grep -Po '\b[^\s-]*\.opf\b'`
   metafound=`zipgrep  '<dc:'$2'>(.*)</dc:'$2'>' "$3" $fileloc`
   echo `expr "$metafound" : '.*<dc:'$2'>\(.*\)</dc:'$2'>.*'`
fi

This uses unzip -l to find out where the .opf file is in the .epub (normally OEBPS\content.opf, but it can be named anything as long as it has the .opf extension). Then it uses zipgrep to find occurrences of the desired metadata type in that file. Finally, strip off the tags to leave just the metadata.

And here's a test run:

beaker$ ./minfo -m title Make_Electronics.epub 
Make: Electronics
beaker$ ./minfo -m publisher Make_Electronics.epub 
O'Reilly Media, Inc.
beaker$ ./minfo -m subject Make_Electronics.epub 

beaker$

That last line is blank because the metadata entry for subject in the opf file is:

<dc:subject/>
6
  • 2
    Very nice. Pretty-much what I wanted. I was checking your code and wanted to ask you about the part you just changed (xxx.opf), as it looked a bit strange. I did not know zipgrep. I slightly changed your script to have less problems with exit depending on how the script is used. Another point: when several meta fields with differing values, the script returns the last one. Also, some meta fileds seem to have a more complicated structure: <dc:creator opf:role="aut">John Doe</dc:creator>. Then I checked only one epub file. But I learned a bunch of things on dealing with such problems.
    – babou
    Mar 28 '16 at 20:46
  • @babou Good edit, thanks. I can modify the regex to handle the case you bring up of the <dc:creator... if you like. Meanwhile I'll have a look at returning multiple values.
    – beaker
    Mar 28 '16 at 21:07
  • Would be great. But I reached my available limit for rep brownie points :-). Then do not spend too much time on it, as there will always more that is asked. I am only surprised the is no standard set of functions for simple manipulation of epub. I am only interested in what does not carry DRM, and I am not even sure it matters much for the rest.
    – babou
    Mar 28 '16 at 21:24
  • What is the "-Po" argument? OS X grey has no -P :-(
    – Paul Waldo
    Jul 13 '17 at 18:14
  • 1
    @PaulWaldo See stackoverflow.com/questions/16658333/…
    – beaker
    Jul 13 '17 at 18:21
11

exiftool can read (but not write) epub meta data. For example

exiftool -T -Title main.epub

1
  • This is actually an excellent answer, which furthermore works also for mobi or PDF (though the metadata info in PDF is not always very informative). It will list complete metadata if the desired one is not specified: exiftool main.epub. If I had not already voted for an answer which helped me a lot, I would choose you as best answer (I know I can change).
    – babou
    Jun 14 '17 at 17:34
7

An EPUB file is just a zip file, and the book's metadata is contained in the OPF (Open Packaging Format) file, which is an XML file. The title is located in the /package/metadata/dc:title element. The other info you're looking for is probably also in children of the metadata element. Here's a good intro to the EPUB format: http://www.ibm.com/developerworks/xml/tutorials/x-epubtut/.

I'm not very familiar with Linux, so I don't know exactly how you'd do all this from the command line. I suspect it would involve writing or finding a script that would uncompress or dig around in the EPUB file, find the OPF file, parse its XML, and locate the element with the metadata you specify, perhaps using XPath.

1
  • Thanks for the pointers. Actually, I was looking for a solution that does a minimal amount of computation. I was going to try it based on your answer, but the next answer seems to do the job.
    – babou
    Mar 28 '16 at 19:33
3

To print out epub metadata,

exiftool yourbook.epub

To edit the metadata, you'd need to unzip it and then zip it back again, as mentioned by others, epub is just a zip file

mkdir tempfolder
mv yourbook.epub tempfolder
cd tempfolder
unzip yourbook.epub
mv yourbook.epub ../youroldbook.epub

Find and edit the metadata in opf file

find . -iname '*.opf'

Metadata would most probably be in the <dc:title> tag,

<dc:title id="pub-title">TITLE OF YOUR BOOK</dc:title>

zip it after editing

zip -rX ../YOUR_BOOK.epub mimetype META-INF/ .
3

with Calibre's ebook-meta

Example output of ebook-meta unixpowertools.epub:

Title               : UNIX Power Tools, 3rd Edition
Author(s)           : Jerry Peek, Shelley Powers, Tim O’Reilly & Mike Loukides [Jerry Peek, Shelley Powers, Tim O’Reilly, and Mike Loukides]
Publisher           : O’Reilly Media
Tags                : COMPUTERS / Operating Systems / UNIX
Languages           : eng
Published           : 2009-02-08T23:00:00+00:00
Rights              : Copyright © 2009 O’Reilly Media, Inc.
Identifiers         : isbn:9780596103699
Comments            : <p>The latest edition of this best-selling favorite is loaded with vital information on Linux, Darwin, and BSD. <i>Unix Power Tools</i> 3rd Edition now offers more coverage of bash, zsh, and other new shells, along with discussions about modern utilities and applications. Several sections focus on security and Internet access. There is a new chapter on access to Unix from Windows, and expanded coverage of software installation and packaging, as well as basic information on Perl and Python.</p>

We can use awk to get at the title:

ebook-meta unixpowertools.epub | awk -F "^Title +: " 'NF > 1 {print $2}'

This produces

UNIX Power Tools, 3rd Edition

for the example file above.

Some ebooks contain the "Title sort" field, which this command doesn't extract but might be relevant to you.

Explanation of the command

  • awk -F "^Title +: sets awk's separator to "Title" (which has to be at the start of a line due to the ^ anchor), followed by at least one whitespace followed by a colon and space.
  • NF > 1 will skip empty lines, where no separator was found
  • {print $2} prints the second colon which is the text after the string matched by ^Title +:

Supported ebook formats

Regarding the supported file formats, I quote from the manual:

Supported formats for reading metadata: azw, azw1, azw3, azw4, cbr, cbz, chm, docx, epub, fb2, fbz, html, htmlz, imp, lit, lrf, lrx, mobi, odt, oebzip, opf, pdb, pdf, pml, pmlz, pobi, prc, rar, rb, rtf, snb, tpz, txt, txtz, updb, zip

Supported formats for writing metadata: azw, azw1, azw3, azw4, docx, epub, fb2, fbz, htmlz, lrf, mobi, odt, pdb, pdf, prc, rtf, tpz, txtz

0
1

Ok, so since nobody has ANY info on this online and this is the top search results. Here is what you are looking for. exiftool -a -u -g1 nameofthe.epub. This line gives you a giant output of all the metadata tags you can extract using exiftool. exiftool -t -Title -Creator -PublicationDate -CreatorFile-as nameofthe.epub this is how you use it. If you push -t lowercase it shows you the description of the tags you pulled. If you run -T uppercase, it just shows the tags. Your welcome. Enjoy.

Edit: Also, since exiftool is a GIANT PITA and their help is semi useless. Here is a few scripts I wrote for it that might help someone out. This took me forever... These are formatted for batch files with %% and ". You may need to edit

This moves any epubs in folder DIR into folders sorted by their Creator (Author).

for %%f in (DIR\*.epubs) do (exiftool "%%f" "-Directory<Creator")

This renames any epubs in a folder, to the Title and Author

for %%f in (01-input\*.epub) do (exiftool "-filename<$title - $creator.%%e" "%%f")

To make them recursive into subdirectories you need to change the for formatting. Example

for /R "01-input" %%f in (*.epub) do (exiftool "-filename<$title - $creator.%%e" "%%f")

Edit2: On the off chance your tags contain "illegal" characters, outlined here (https://exiftool.org/filename.html), place the tag inside {} and put a ; at the end of the tag. This strips those out so it works. Example script.

for /R "01-input" %%f in (*.epub) do (exiftool "-filename<${title;} - ${creator;}.%%e" "%%f")
0

Expounding on @pheon's answer, I created this shell script

#!/bin/bash

exiftool="/usr/local/bin/exiftool"

filename=$(basename "$1")
extension="${filename##*.}"
filename="${filename%.*}"
directory=$(dirname "$1")
newfilename=`${exiftool} -T -Title $1`

echo mv "$1" "${directory}/${newfilename}.${extension}"
mv "$1" "${directory}/${newfilename}.${extension}"

Just run the script, passing the pub filename and it will rename it in-place to be the title of the eBook. Note that it is likely there will be spaces in the filename.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.