Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have this bash:

  replace="s/AAAA/BBBB/g";
  find myDirectory/. -type f -print0 | xargs -0 sed -i $replace;

that will recursively scan myDirectory tree and replace all occurrences of AAAA with BBBB on the files there.

But I want to limit this to happen on files of specific extensions, for example, .txt, .read, .po

How do I impose this limit?

share|improve this question
add comment

3 Answers 3

up vote 4 down vote accepted

You can use the -name option for find to restrict matches based on filename.

find myDirectory/. -type f -name '*.txt' -print0 | xargs -0 sed -i "$replace"

For multiple extensions, you can use -o (or) and group them with ().

find myDirectory/. -type f \( -name '*.txt' -o -name '*.read' \) -print0 | xargs -0 sed -i "$replace"

Another improvement that can be made is using -exec instead of xargs. This is more portable and eliminates a subshell.

find myDirectory/. -type f -name '*.txt' -exec sed -i "$replace" {} +
share|improve this answer
    
2nd option working for me... thanks!!! –  Digital Robot Jan 7 '13 at 2:27
add comment

Add these settings to your .bashrc:

shopt -s extglob globstar

extglob turns on some additional patterns, including the @(…) construct for disjunction. globstar turns on **/ which traverses directories recursively.

Then you don't need to use find:

sed -i "$replace" mydirectory/**/*.@(txt|read|po)

In zsh, you don't need any special option, just run

sed -i $replace mydirectory/**/*.(txt|read|po)

If you have a lot of files, you may see a message like “command line length limit exceeded”. But the limit is very high on modern Linux systems, you're unlikely to encounter it.

share|improve this answer
add comment

From the manual (man find), look under operators by typing /OPERATORS then Enter.

find myDirectory/ -name '*.txt' -o -name '*.txt' -o -name '*.read' -o -name '*.po'
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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