# Bash script to clear files not matching a given extension

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* foo.tex foo.aux foo.log foo.bbl foo-blx.bib$ 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}
fi
}


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? - Which basename are you using? I am not familiar with (and can't find) the -s option for it. – rolfl Mar 27 '14 at 23:22 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? – WChargin Mar 27 '14 at 23:26 Essentially that fragment just trims the .tex suffix if there is one. So, cleantex foo is the same as cleantex foo.tex. – WChargin Mar 27 '14 at 23:27 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 – rolfl Mar 27 '14 at 23:31 ## 2 Answers 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 name=${1%.tex}
test -f $name.tex || return 1 rm -f$name{.!(*tex),-blx.bib}
fi
}


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.
-