Using LaTeX creates a bunch of auxiliary files like foo.aux, foo.log, etc. Sometimes, I want to create a clean run of my document. I usually manually execute this in the terminal as

$ ls foo*
$ rm foo{.aux,.log,.bbl,-blx.bib}

This works fine. However, it is error-prone and I don't want to accidentally erase my .tex file. So I added this function to my ~/.bashrc:

# Delete all non-TeX files
# invoke as: cleantex foo
# where: foo.tex, foo.aux, foo.log, etc. are files in directory
cleantex () {
    if [ -n "$1"]; then
        name = $(basename -s ".tex" "$1")
        rm -f $name{.!(*tex),-blx.bib}

My question is about the key line

rm -f $name{.!(*tex),-blx.bib}

that actually executes the script.

Is this line well-written? What might I improve here?

  • \$\begingroup\$ Which basename are you using? I am not familiar with (and can't find) the -s option for it. \$\endgroup\$ – rolfl Mar 27 '14 at 23:22
  • \$\begingroup\$ I'm on Linux Mint 16 with GNU coreutils 8.20. My man basename has the option, as does the official documentation. Is your distribution out of date? \$\endgroup\$ – wchargin Mar 27 '14 at 23:26
  • \$\begingroup\$ Essentially that fragment just trims the .tex suffix if there is one. So, cleantex foo is the same as cleantex foo.tex. \$\endgroup\$ – wchargin Mar 27 '14 at 23:27
  • \$\begingroup\$ That option is not available on RHEL 6.4, Ubuntu 12.04 LTS ... which itself may be a problem. (I work in an 'enterprise'). Also, the basenames I have all will work that way without the -s option basename foo.tex .tex will produce foo. Food for thought \$\endgroup\$ – rolfl Mar 27 '14 at 23:31

My real concerns with the script are:

  • cleantex path/to/file.tex will not delete files in that path, but in the current directory.
  • you should check the actual .tex file exists before you delete all the things around it.
  • the brace-expansion is unnecessarily complicated...... especially when combined with the extended glob !(*tex). I would manually resolve the brace-expansion so that there is only one complicated operation on that line.
  • I would use actual glob-expansion and only delete existing files.... and not use the -f option on rm (which does more than just suppress the error message if files do not exist....)

Mostly minor things:

  • [ -n "$1" ] is equivalent to [ "$1" ]. I'd go for the shorter one
  • Since you are in bash, you can use a variable substitution ${1%.tex} instead of basename, which is slightly better
  • There cannot be spaces around the = sign in assignments: name = val is incorrect, should be name=val
  • As @rolfl suggested in his answer, it would be better to check if a tex file exists before deleting anything

Putting it all together:

cleantex () {
    if [ "$1" ]; then
        test -f $name.tex || return 1
        rm -f $name{.!(*tex),-blx.bib}

Some extra remarks:

  • I would add the -v flag for the rm, so that it will print what it actually removed: rm -vf $name{.!(*tex),-blx.bib}
  • I guess you will never create .tex files with spaces in the name. If you ever do, you'll need to quote $name, for example: rm -f "$name"{.!(*tex),-blx.bib}
  • I would drop the -f flag from rm. Sure, there will be some error messages that way when there's nothing to delete, but I don't see that as a bad thing.

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.