# Unused bibliography entries - how to check which entries were not used?

This question led to a new package:
checkcites

While reading papers, I put those that I'd like to refer to or mention in customized .bib files (one .bib file for each paper). (Thanks to Mendeley it's pretty easy and straight forward - they call it "collections").

My intention is that all entries in the .bib file should be mentioned in the text.

How to check which bibliography entries I have not referred to ?

-
If tex code would be helpfull here, or more details, please let me know, I'd love to improve question. –  Grzegorz Wierzowiecki Feb 3 '12 at 13:23
Only those entries \cited will appear in the bibliography. If you want to make a .bib file that consists of only those entries cited, then see this: tex.stackexchange.com/questions/32032/… –  Seamus Feb 3 '12 at 13:28
If you are in a unix-like environment, I can write for you a short script that does exactly what you need. The information on used references is stored in the .aux file in the form \citation{ref-label}. –  yo' Feb 3 '12 at 13:29
Maybe you could extract the cited references from your .bib file using bibexport to a new file and then diff both to see the differences. –  Paulo Cereda Feb 3 '12 at 13:33

Another way is to use the refcheck package and add \nocite{*} in your document. This package will warn you (amongst other things) about unused references. My MWE:

\begin{filecontents}{\jobname.bib}
@BOOK{foo:2012a,
title = {My Title One},
publisher = {My Publisher One},
year = {2012},
editor = {My Editor One},
author = {Author One}
}

@BOOK{foo:2012b,
title = {My Title Two},
publisher = {My Publisher Two},
year = {2012},
editor = {My Editor Two},
author = {Author Two}
}

@BOOK{foo:2012c,
title = {My Title Three},
publisher = {My Publisher Three},
year = {2012},
editor = {My Editor Three},
author = {Author Three}
}
\end{filecontents}

\documentclass{article}

\usepackage{refcheck}

\begin{document}

Hello world \cite{foo:2012a,foo:2012b}.

\nocite{*}

\bibliographystyle{plain}
\bibliography{\jobname}

\end{document}


The output:

The reference keys not cited in your document will be displayed between ?...?. Besides, refcheck adds the following line to your .log file:

<Info by RefCheck> Unused bibitem foo:2012c' on page 1.


Hope it helps. :)

Update: Based on this question, egreg and I came up with a Lua script called checkcites. The idea of this script is to detect unused or undefined references from LaTeX auxiliary (.aux) or bibliography (.bib) files.

Consider the following example: document.tex

\begin{filecontents}{\jobname.bib}
@BOOK{foo:2012a,
title = {My Title One},
publisher = {My Publisher One},
year = {2012},
editor = {My Editor One},
author = {Author One}
}

@BOOK{foo:2012b,
title = {My Title Two},
publisher = {My Publisher Two},
year = {2012},
editor = {My Editor Two},
author = {Author Two}
}

@BOOK{foo:2012c,
title = {My Title Three},
publisher = {My Publisher Three},
year = {2012},
editor = {My Editor Three},
author = {Author Three}
}

@BOOK{foo:2012d,
title = {My Title Four},
publisher = {My Publisher Four},
year = {2012},
editor = {My Editor Four},
author = {Author Four}
}
\end{filecontents}

\documentclass{article}

\begin{document}

Hello world \cite{foo:2012a,foo:2012c},
how are you \cite{foo:2012e}, and
goodbye \cite{foo:2012d,foo:2012a}.

\bibliographystyle{plain}
\bibliography{\jobname}

\end{document}


After compiling it, an auxiliary file document.aux will be generated. Now we will use texlua (which is available in both MiKTeX and TeX Live distros) to run checkcites on the .aux file:

$texlua checkcites.lua document.aux  The script will look for all unused and undefined references. The output will be: If you want to look only for unused references in your .bib file, you can add the --unused flag: $ texlua checkcites.lua --unused document.aux


The argument order doesn't matter, so you can also call:

$texlua checkcites.lua document.aux --unused  Similarly, using $ texlua checkcites.lua --undefined foo.aux


will make the script only look for undefined references in your .tex file.

To look for both unused and undefined references, you can also use the --all flag. If no flag is provided, checkcites will behave as if --all was provided.

The script is now available on CTAN and tlmgr will install it on TeX Live 2011 (or later). Hope you guys like our humble script. :)

Update: As checkcites is now available on CTAN and TeX Live, there's no need of explicitly calling texlua nor the original checkcites.lua file; a simple call to

$checkcites --unused document.aux  will suffice, since the script is properly wrapped. :) - Wow, I was not aware of this package before. Pretty elegant! – Daniel Feb 3 '12 at 22:56 Very nice package. I was wondering, is it possible to extend the package so that it creates an output file? for example, a latex file that cites the uncited entries. Or at least a simple text file with the list of unused entries that the user can later exploit to generate the report. It can be useful when you are collaborating and you want to send a PDF with this information to your coworkers. Thank you! – Felipe Aguirre Aug 23 '12 at 7:33 I just tested it with my Thesis.tex which is divided in several .tex files (I use \included to input each chapter). Sadly, checkcites does not work in this case. A citation in Chap1.tex is logged in Chap1.aux, so there is no record of it in Thesis.aux. I naively tried to run checkcites to Chap1.aux, but it does not have \bibdata with the the name of the .bib, so it won't be able to find the bibliography to compare with. Any ideas? Anyway, it is still a great package. – Felipe Aguirre Aug 23 '12 at 7:50 Hi @Felipe! :) Thanks for the feedback. Currently, checkcites can handle multiple .bib files, but AFAIK only one .aux file. I'll take a look at the code and try to work on an improved version. :) About the output to an external file, a workaround for now would be to redirect the output with $ checkcites mydoc.aux > out.txt. Hope it helps. :) –  Paulo Cereda Aug 23 '12 at 10:15
That is a good solution for the moment. Although, I encourage you to add the functionality of creating a PDF output. It would be much more elegant! I would do it myself, but I don't know LUA and I am writing my thesis, I don't have much time. Thank you!! –  Felipe Aguirre Aug 23 '12 at 10:47

One possibility would be the following:

1. Switch the bibtex bibliography style to unsrt (with biblatex pass the sorting=none option)
2. Compile your document --> PDF with cited references
3. At the very end of your document (before the \bibliography command) add a \nocite{*}
4. Compile your document --> PDF with all references
5. Compare the bibliography of both PDFs. The "extra" entries at the end are those you have not yet cited.

However, if you work in a UNIX-like environment, I would probably use tools like grep and sed to extract the keys from the .aux file and the .bib file and diff them:

cat paper.aux | grep '\\citation' | sed -e 's/\\citation{$$.*$$}/\1/g' -e 's/ *$$.*$$ */\1/g' | tr ',' '\012' | sort -u > paper.keys
cat paper.bib | grep "@.*{.*," | sed -e 's/.*{$$.*$$,/\1/' | sort -u > bib.keys
grep -v -f paper.keys bib.keys


The first line extracts all keys given in \citation{key1[,key2 ...]} commands from the aux-file into distinct lines, sorts and unifies them (every entry is contained once once) and redirects the result into the file paper.keys. The second line does the same for the keys contained in @<some type>{key, lines in the bib file. The third line prints out every line from bib.keys that is not contained in paper.keys, which is the delta you are interested in.

-
Why the four backslashes in the argument to grep? And wouldn't it be simpler starting with grep '\\citation' paper.aux? –  egreg Feb 3 '12 at 14:39
@egreg I think that Daniel took it from me ;) and these things are just a matter of habit I think ;) –  yo' Feb 3 '12 at 15:04
@tohecz Well, on my system it doesn't work with four backslashes. –  egreg Feb 3 '12 at 15:06
@egreg: tohecz an me discussed how to build this line in another question, he is right that I took the grep part from him. The point is: If you put the parameter in double quotes, the shell will substitute them down to two backslashes and grep down to one. If you put it in single quotes (which you probably tried) the shell will not perform substitution, so four backslashes are passed to grep, hence the pattern does not match. I have modified the solution to use single quotes. –  Daniel Feb 3 '12 at 16:37
@egreg: I prefer cat <file> | grep <expression> just because it is then more visible which <file> I am working on (especially if <expression> is nontrivial). This is slightly slower, though. –  Daniel Feb 3 '12 at 16:40

Given that you are using bibtex and not biblatex, the Bibtool utility may be able to help you. Say you have a myreferences.bib file you've created in Mendeley or wherever. You write paper.tex with the intention of explicitly citing every item from myreferences.bib. To see if you've forgotten anything, use bibtool to extract a bibliography of all and only the references cited in paper.tex and compare its contents to the original:

bibtool -x paper.aux -o paperrefs.bib


Now you can compare paperrefs.bib to myreferences.bib:

diff myreferences.bib paperrefs.bib


Ideally you'll find there's no difference. You could probably work this up into a script of the sort mentioned by tohecz, but using bibtool means you don't have to come up with a regular expression to catch the various forms of citation. Your original myreferences.bib should be sorted alphabetically for this to work properly.

-

This answer will give you a clue, but only for biblatex, I believe. (I won't duplicate it here)

It allows you to use \nocite{*} to place all the unreferenced .bib file entries in a separate section of the bibliography.

Normally, one might publish this as 'additional reading', for example, but in your case you can use it to help prune your .bib file.

-
This works only with biblatex. I don't think that the OP uses biblatex ... P.S. I guess you mean \nocite{*} instead of \nocite(*) –  Thorsten Feb 3 '12 at 13:36
@Thorsten: Thanks, I've sorted that out. –  Brent.Longborough Feb 3 '12 at 14:30

Under unix-like systems, you can make a following bash script, called e.g. diffrefs:

#!/bin/bash
$f=${1%.???}
cat $f.aux | grep "\\\\citation" | sed -e 's/\\citation{$$.*$$}/\1/g' -e 's/ *$$.*$$ */\1/g' | sort | uniq >$f.cit
cat $f.bib | grep "^@" | sed 's/.*{\|,.*//g' | sort >$f.bit
echo "Unused but defined references:"
diff $f.cit$f.bit | grep "^>"
echo "Undefined but used references:"
diff $f.cit$f.bit | grep "^<"


Usage: diffrefs myfile

Explanation:

• cat $f.aux ...: outputs the auxiliary file (cat), takes the information on used citations (grep), extracts the labels, removes white-space (sed), sorts and removes duplicates (sort, uniq) • cat$f.bib ...: outputs the bibtex file (cat), takes the first line of each entry (grep) removes evertything before { and after , (sed), and does sort, uniq as before.
• diff ...: prints differences between two files, the characters < and > say "which file is larger by that line"

Edit: I found that LaTeX automatically perorms the comma-seperation of \cite{...} parameter, so I removed it from the script.

-
No, the argument to \citation can contain commas, depending on the package used for citation, for instance natbib. –  egreg Feb 3 '12 at 14:43

This question deserves a brief answer to demonstrate how simple checkcites actually is. At your prompt simply type ...

\$ checkcites my_document.aux


... and it prints out a nicely formatted list of unused + undefined references.

This works out-of-the-box if you have a full installation of a recent TeX-Live distribution (2011+), where the command checkcites should already by on your path. It's a simple command line tool; no modification in your document is required (e.g. usepackage).

I hope my answer will prevent others to manually download the script from CTAN, study the docs, just to find out that RTFM is overkill in this case :).

-

Since I ran into some issues with the refcheck package, a rather simple option would be to load hyperref with the pagebackref option. Then, doing a \nocite{*} in the main TeX file, the bibliography gets back references to the pages where an entry was cited. No citation -> no back reference.

\begin{filecontents}{\jobname.bib}
@BOOK{foo:2012a,
title = {My Title One},
publisher = {My Publisher One},
year = {2012},
editor = {My Editor One},
author = {Author One}
}

@BOOK{foo:2012b,
title = {My Title Two},
publisher = {My Publisher Two},
year = {2012},
editor = {My Editor Two},
author = {Author Two}
}

@BOOK{foo:2012c,
title = {My Title Three},
publisher = {My Publisher Three},
year = {2012},
editor = {My Editor Three},
author = {Author Three}
}
\end{filecontents}

\documentclass{article}

\usepackage[pagebackref]{hyperref}

\begin{document}

Hello world \cite{foo:2012a,foo:2012b}.

\nocite{*}

\bibliographystyle{plain}
\bibliography{\jobname}

\end{document}
`
-