Recursively rename files using find and sed
Solution 1
If you don't have rename
(it's a really short Perl script) or your rename is the more simplistic util-linux version or you simply want to know how to make your command work: you just need to send it to the shell for execution:
find spec -name "*_test.rb" -exec sh -c 'echo mv "$1" "$(echo "$1" | sed s/test.rb\$/spec.rb/)"' _ {} \;
Solution 2
Too complicated. If you have the rename
command available, you could try the following:
find . -name "*_test.rb" -print0 | xargs -0 rename "s/_test/_spec/"
This finds the relevant files, sends them to xargs which in turn uses the rename tool (which renames files according to the given perl regex).
Related videos on Youtube
superflux
Updated on September 18, 2022Comments
-
superflux over 1 year
I want to go through a bunch of directories and rename all files that end in _test.rb to end in _spec.rb instead. It's something I've never quite figured out how to do with bash so this time I thought I'd put some effort in to get it nailed. I've so far come up short though, my best effort is:
find spec -name "*_test.rb" -exec echo mv {} `echo {} | sed s/test/spec/` \;
NB: there's an extra echo after exec so that the command is printed instead of run while I'm testing it.
When I run it the output for each matched filename is:
mv original original
i.e. the substitution by sed has been lost. What's the trick?
-
DerfK over 13 yearsI can tell you what's wrong, but I'm not sure how to tell you to fix it: bash is immediately executing
echo {} | sed s/test/spec/
, which produces {}, then bash executes the find command. Have you checked to see whether your distribution has a goodrename
program? -
Dennis Williamson over 13 yearsPlease don't cross-post.
-
-
SmallClanger over 13 years+1 for
-print0
. Also, I'd make the regexp pattern as axplicit as possible:"s/_test.rb$/_spec.rb/"
just to be on the safe side. -
Phil Hollenback over 13 yearsnote that only works if you happen to have the perl script version of rename, not the standard rename that comes with util-linux.