Wednesday, January 30, 2008

How to find multiple file types using linux's "find"

I've always found *nix's "find" and "grep" rather hard to use. Not only are there different flavors of regular expressions to use, but mainly different syntax. For find, the directory you're searching for comes first. For grep, it comes last. To find the negation of something, you'd use "-not" and for grep it's "-v". pain.

Anyway, been trying to learn my tools better, and I found out how to grep and replace expressions across multiple files through emacs. Since rails uses all sorts of file extensions, naturally, I wanted to grep for find different files types. I had thought the -name options took regexs (it doesn't), so I had tried it in regex (no go)...only to find that it's something like this:

find . -name "*.rb" -o -name "*.rhtml"

the -o is the equivalent of a boolean "or". small tip...

11 comments:

  1. Thanks for the tip, was just struggling with this myself.

    ReplyDelete
  2. thanks for that. it helped me for the same reason. regex syntaxes give me a headache as they differ between apps.
    That's the beauty of standards - there are so many of them :P

    ReplyDelete
  3. You can always use the -regextype to make regex play nice. The problem with using -o is that if you want to pass all of your results to a program as a list with -exec you can't because there needs to be a seperate -exec before each -o.

    For instance I wanted to search my music directory or videos and pass them all to mplayer to be played in a random order but I had multiple file types in multiple locations, this is what I came up with:

    find ./ -regextype posix-awk -regex "(.*.mpg|.*.avi|.*.wmv|.*.mpeg)" -exec mplayer -shuffle -loop 0 {} +

    ReplyDelete
    Replies
    1. Anonymous11:16 AM

      Note that the regex .*.mpg would match a file named foo.barmpg.
      This happened to me when trying to match .*.sh and all of my .bash files where getting matched.
      If you escape the period, .*\.sh, then only files strictly ending with .sh will get matched.

      Delete
  4. Anonymous12:15 PM

    thank you for tipe

    ReplyDelete
  5. Anonymous3:21 AM

    After spending 30 minutes with "man find" I got frustrated and used search engine and after 5 minutes found this site and got my problem solved. Thank you!

    ReplyDelete
  6. Anonymous7:12 AM

    find file extensions .c and .h

    find . -name "[*.ch]"

    ReplyDelete
  7. Anonymous7:02 AM

    Thanks for the tip. Was exactly what I was looking for.

    ReplyDelete
  8. Anonymous8:10 PM

    thanks...it helped a lot...Appreciated your efforts

    ReplyDelete
  9. Anonymous2:42 PM

    % find . -name "*.[ch]" -exec grep -l "stringToFind" {} \;

    ReplyDelete
  10. Anonymous3:07 AM

    find . -name *.c -print -o -name *.h -print | xargs grep expression_to_grep

    I don't like the -print there a couple of times, but I couldn't find a way to make it work without the double -print

    ReplyDelete