$ find . -name *.d -delete
which finds all files with the extension .d and deletes them.
Well, yesterday, I was trying to do something a bit complicated, apparently. I wanted to grep for files with a certain pattern but where the filenames end in ",v". So naturally, I typed:
$ find . -name *,v
There was other stuff after that, 'xargs' and 'grep' (don't ask--'cvs' is my mortal enemy and it has to do with that.). But the line above illustrates the issue.
Anyway, I got this error message:
find: paths must precede expression
Huh? Paths must precede expression? What paths? What expression? Is it the comma? Naturally, I had to google to find the answer. What did linux people do before google. I got the answer but still didn't know what was wrong. Then this morning I googled some more and finally learned why it was a problem.
Here it is. The bash shell does something called globbing. That means, when you put wildcards on the command line, it looks for all files that match that pattern and then, if there is something, replaces the expression with the wildcards with that list.
So if I'm in the directory that has no *.d files, *.d doesn't turn into anything and hence, isn't replaced. So the first line above works fine.
But in the case of the *,v file, there were files that matched that. So behold the following example where I make a directory and create 2 empty files in it:
$ mkdir -p /tmp/test
$ cd /tmp/test
$ touch a,v
$ touch b,v
$ find . -name *,v
I'll get an error. Why? Because even though I typed find . -name *,v, the find command doesn't get ".", "-name", and "*,v". No, the *,v is replaced with "a,v b,v" so find gets ".", "-name" "a,v", and "b,v". So it thinks I'm looking for only files named "a,v" and that I want to "b,v" them. I guess... I still don't get the "paths must precede expression" but at least I know why there is a problem.
The solution? Quotes. Double or single. Doesn't matter if you're not using variables.
$ find . -name '*,v'
This does what I want.