John
John

Reputation: 539

Edit all files at depth 2

I'd like to perform an edit on every file named "game.ml" at depth 2 in a certain file hierarchy. My thought was to write

find myfiles -depth 2 -type f -name "game.ml" -exec sed -e 's/size = 5/size = 6/'  '{}' > game2.ml  \;

and then go back through the directory again and move all the "game2.ml" files back to game.ml, overwriting the originals. Really, what I want is sort of a "self-sed" operation, but I don't know of one.

The bad news is that the find command above doesn't put game2.ml into the directory where game.ml was, but into the directory from which the find was invoked.

Can someone suggest a way to fix this particular problem, or a better way to approach the whole task? Either would make me happy.

Upvotes: 0

Views: 27

Answers (2)

rob mayoff
rob mayoff

Reputation: 385950

You can find all of the files you want without find, with the shell pattern myfiles/*/game.ml.

You can edit them in-place more easily with perl than with sed:

perl -p -i.bak -e 's/size = 5/size = 6/' myfiles/*/game.ml

The -p flag prints each input line to the output file (after expressions are evaluated). The -i.bak edits each file in place, saving the original with a .bak extension (so, game.ml.bak). The -e flag executes the following expression on each line of each file.

If you really want to do it with sed:

for f in myfiles/*/game.ml; do
    sed 's/size = 5/size = 6/' < "$f" > "$f".new && mv "$f".new "$f"
done

Upvotes: 1

anubhava
anubhava

Reputation: 785846

For POSIX you may use this find:

find myfiles -depth 2 -type f -name "game.ml" |
while IFS= read -rd '' file; do
   sed 's/size = 5/size = 6/' "$file" > game2.ml
done

Upvotes: 1

Related Questions