1

I'm currently learning bash, and came upon the find command. I'd like to use it to, say, find and rename all .py files to .bak (for example, hello.py should be renamed hello.bak).

I think I should be able to write a command like this:

find -name "*.py" -exec mv {} NEW_NAME \;

where NEW_NAME stands for the renamed {}.

I've tried various convoluted approaches, amongst which

  • assigning {} to a variable: I'm unable to do a variable assignment (-exec a=1 for example returns an error)

  • piping commands, but even though echo $(echo ./hello.py | cut -d'.' -f2).bak returns /hello.bak as expected, replacing NEW_NAME with $(echo {} | cut -d'.' -f2).bak doesn't.

  • Finally (thanks to the following link: Changing arguments of {} find exec ), I was able to achieve my goal with find -name "*.py" -exec bash -c 'mv $0 ${0/.py/.bak}' "{}" \;

I have a feeling though that there's a simpler way to do this, and that I'm overlooking something obvious.

Edit: I'm aware there are other ways to batch rename files than with find ... -exec ...; I'm specifically looking for a better/simpler way to do this with this command (I was hoping for some Linux equivalent to Python's .replace() string method).

Swifty
  • 2,630
  • 2
  • 3
  • 21
  • 1
    There are a bunch of different ways to rename things in linux. See http://mywiki.wooledge.org/BashFAQ/030 for some options in addition to `find`. – j_b Mar 10 '23 at 15:01
  • Thanks for your comments; @j_b: I know there are other ways, but I was specifically looking for a method using `find ... -exec ...` (hopefully simpler than the one I found). – Swifty Mar 10 '23 at 16:21

1 Answers1

4

You're not missing anything, the UNIX way of doing it is like so:

find . -type f -name '*.py' -exec sh -c '
for src; do
  mv "$src" "${src%.*}.bak"
done' sh {} +
oguz ismail
  • 1
  • 16
  • 47
  • 69
  • 1
    Thanks, so it seems there's nothing really simpler than what I already arrived to. I was hoping for some Linux equivalent o Python's `.replace()`. – Swifty Mar 10 '23 at 16:19
  • 1
    There are third-party `rename` commands which work this way, but nothing completely standard, as in POSIX. In fact, there are multiple `rename` commands with different features and different syntax. – tripleee Mar 13 '23 at 06:14