15

I am completely new at Bash but I just can't seem to find a way to make it do what I want.

Imagine you have a tree directory with 2 files: /top.php and /test/bottom.php

How do I make my function look and replace say "hello" into "bonjour" in /top.php AND in /test/bottom.php?

So far the only way I have found to do this is by calling the same function twice with a different depth level:

find ./*.php -type f -exec sed -i 's/hello/bonjour/' {} \;
find ./*/*.php -type f -exec sed -i 's/hello/bonjour/' {} \;

Surely there's a recursive way to do this in one line?

Erken
  • 1,448
  • 16
  • 23
  • possible duplicate of [Awk/Sed: How to do a recursive find/replace of a string?](http://stackoverflow.com/questions/1583219/awk-sed-how-to-do-a-recursive-find-replace-of-a-string) – AncientSwordRage May 07 '15 at 08:17

3 Answers3

37

Use an actual pattern for find instead of shell wildcard expansion:

find . -name '*.php' -type f -exec sed -i 's/hello/bonjour/' {} \;
thiton
  • 35,651
  • 4
  • 70
  • 100
2

Close:

find -iname '*.php' -type f -exec sed -i 's/hello/bonjour/' {} \;

Or

find -iname '*.php' -type f -print0 |
     xargs -0 sed -i 's/hello/bonjour/'
sehe
  • 374,641
  • 47
  • 450
  • 633
  • the first solution you gave didn't work. I haven't tried the second one but the solution given by thiton was more straight forward – Erken Nov 21 '11 at 20:18
  • @Erken: that is because you had more files in the top directory than the question described. Learn to quote your wildcards if you don't want them expanded. – sehe Nov 21 '11 at 20:19
-2

Use xargs and grep:

find . -type f | grep php$ | xargs -n1 -i sed -i 's/hello/bonjour/' {}

Here's how it works:

Find all files in-and-below current directory:

find . -type f

Include just those files ending in php:

grep php$

Take each line and apply sed to it:

xargs -n1 -i sed -i 's/hello/bonjour/' {}
Stephen Gross
  • 5,274
  • 12
  • 41
  • 59