Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Possible Duplicate:
Deleting all files in a folder except files X, Y, and Z

I am writing a script to compile many .tex files. After that, many auxiliaries files were created.

So, I would like to remove them at the end of the script. I tough to use rm $file.xxx but I would have to write all the extensions by hand, since that I want to keep my source file and the pdf output, so I can not use the * to delete all.

How to delete all the extensions except those with extension .tex/.pdf?


share|improve this question

marked as duplicate by jasonwryan, Gilles, Warren Young, Renan, Ulrich Dangel Aug 31 '12 at 12:36

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

See the duplicate question. But I do not recommend doing it that way. You risk accidentally deleting an important file. It's better to enumerate the extensions to delete, that way if you forget one you won't lose data. Pass the -f option to rm so that it doesn't complain if there is no file with one of the extensions (rm -f *.aux *.bbl *.blg *.idx *.ilg *.ind *.lof *.log *.lot *.toc …). – Gilles Aug 30 '12 at 1:21
@Gilles, thanks. Now I guess that it'll work. I didn't know about the -f option. – Sigur Aug 30 '12 at 1:24
up vote 1 down vote accepted

Well, you could just ignore the rm errors, but that's not elegant :).

Add a function like this to your ~/.bashrc:

 function cleantex () {
   find . -name "$1*" | grep -vP '.tex$|.pdf$' | while read -r i; do rm "$i"; done    

You then call it with the (unique) beginning of your filename like so:

 $ cleantex mytexfile

It will delete all files in the given directory that start with $file and do not end in .tex or .pdf. The $ makes sure the match is only at the end of the file, the extension. Otherwise it will ignore files like footexfoo.aux because the file name contains tex. You can add as many extensions to ignore as you want:

 function cleantex () {
       find . -name "$1*" | grep -vP '.tex$|.pdf$|.foo$|.bar$' | while read -r i; do rm "$i"; done    

If you want to remove these files from within a bash script, you don't really need the function. Just add this line to your script (changing mytexfile to whatever your tex file is called):

find . -name "mytexfile*" | grep -vP '.tex$|.pdf$' | while read -r i; do rm "$i"; done

Finally, if you want to be able to do this for all tex files, whatever their name, use:

find . -name "*.tex" | sed 's/\.tex$//' | while read -r name; do 
    find . -name "$name"* | grep -vP '.tex$|.pdf$' | while read -r i; 
        rm "$i"; 
share|improve this answer
Thanks. Is it possible to define this function inside my .sh file instead of create another one? Second, to protect also pdf file I should define other function or is it possible to add this extension to the same function? – Sigur Aug 30 '12 at 1:50
@Sigur By .sh you mean bash.rc? In any case no, no need for a new file just add this function to your existing bash settings file. As for the pdf, I already updated my question before seeing your comment :) – terdon Aug 30 '12 at 1:53
I mean, I am writing a file in my /usr/bin called fastex.sh to do many things to me. So, my question is: may I declare your function inside this file or I must to define it inside bash.rc. I am asking because I will share this script with other computers, so I would like to send only this script. – Sigur Aug 30 '12 at 1:57
All of these examples will break on files that contain spaces, and parsing ls output is always wrong – jordanm Aug 30 '12 at 3:04
@jordanm Actually, none of these examples will break on names with spaces. Notice the quotes around $name and $i and the use of read. As you can see in the official BASH FAQ, the first question there recommends using a while loop with read specifically to deal with file names containing spaces. Still, you're right about ls. Changed to find. – terdon Aug 30 '12 at 3:31

You can use:

rm *.{extension1,extension2,extension3}

Alternatively you can use:

shopt -s extglob
rm !(*.tex|*.pdf)

This will erase all but the files you want to keep, in this case the *.tex and *.pdf.

Hope it helps!

share|improve this answer
OP has explicitly requested a solution that does not involve specifying all of the relevant extensions... – jasonwryan Aug 30 '12 at 1:02
@alemani, thanks. @jasonwryan, exactly. The problem is that the $file.aux always will be created but for example $file.lof won't. So, if I write all the extensions by hand, even if only one time, I could get some errors in case of non existing files. By the other hand, rm $file.{* minus {.tex}} will not produce an error, since that it includes the aux files. – Sigur Aug 30 '12 at 1:08
@alemani, it does not work. I got the error 'couldn't remove $file.{xxx,xxx}'. File not found. – Sigur Aug 30 '12 at 1:13
@Sigur It should work, like: rm *.{aux,log,lof} another method is to use: shopt -s extglob then rm !(*.pdf|*.tex) this way erases all but the files you want to keep. – alemani Aug 30 '12 at 1:24
@alemani, how to say that I want to delete only files named by $file and not all the files except pdf and tex? – Sigur Aug 30 '12 at 1:29

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