19

I was wondering if this is possible in find command. I am trying to find all the specific files with the following extensions then it will be SED after. Here's my current command script:

find . -regex '.*\.(sh|ini|conf|vhost|xml|php)$' | xargs sed -i -e 's/%%MEFIRST%%/mefirst/g'

unfortunately, I'm not that familiar in regex but something like this is what I need.

user3282191
  • 203
  • 1
  • 2
  • 7
  • 1
    did you check with `man find` that your version of find has the `-regex` option? Not all do. Are you saying it doesn't work. Looks OK to me, but I my systems doesn't have `find . -regex`, so I can't say for sure. Good luck. – shellter Mar 25 '14 at 03:30
  • 2
    Hi shellter, I finally got it! `find . -regex ".*\.\(sh\|ini\|conf\|vhost\|xml\|php\)" -print | xargs sed -i -e 's/%%MEFIRST%%/mefirst/g'` These script will select all the files with the following extensions: sh, ini, conf, vhost, xml, php and will replace the text %%MEFIRST%% to mefirst inside the files selected. – user3282191 Mar 25 '14 at 03:33
  • 2
    you can post your answer below and after ~48 hrs, accept your own answer, for reputation points here on S.O. Welcome and good luck. – shellter Mar 25 '14 at 03:34
  • thanks shellter! noted. – user3282191 Mar 25 '14 at 03:37
  • Just a note: with find you can also do: find -name "*.sh" -or -name "*.ini" -or -name "*.conf" .... Of course, your solution is more elegant. – NotANumber Apr 24 '14 at 20:52

1 Answers1

28

I see in the comments that you found out how to escape it with GNU basic regexes via the nonstandard flag find -regex RE, but you can also specify a type of regex that supports it without any escapes, making it a bit more legible:

In GNU findutils (Linux), use -regextype posix-extended:

find . -regextype posix-extended -regex '.*\.(sh|ini|conf|vhost|xml|php)$' | …

In BSD find (FreeBSD find or Mac OS X find), use -E:

find . -E -regex '.*\.(sh|ini|conf|vhost|xml|php)$' | …

The POSIX spec for find does not support regular expressions at all, but it does support wildcard globbing and -o (for "or"), so you could be fully portable with this verbose monster:

find . -name '*.sh' -o -name '*.ini' -o -name '*.conf' \
  -o -name '*.vhost' -o -name '*.xml' -o -name '*.php' | …

Be sure those globs are quoted, otherwise the shell will expand them prematurely and you'll get syntax errors (since e.g. find -name a.sh b.sh … doesn't insert a -o -name between the two matched files and it won't expand to files in subdirectories).

I'm also guessing you want -iregex or -iname rather than -regex or -name so the search is case-insensitive.

Adam Katz
  • 14,455
  • 5
  • 68
  • 83