2

I have a lot of directories. Each one of these has a file with a specific extension .ext.

I want to rename these files.

Example:

// Note: The names are random, can have spaces and special characters

Parent
 |
 |- First Directory
 |   |
 |   |- Some file.txt
 |   |- Another one.pdf
 |   `- The one to rename.ext
 |
 |- Second Directory
 |   |
 |   |- Some file.txt
 |   |- Another one.pdf
 |   `- The one to rename.ext
[…]

I want to rename all the file with the .ext extension to new name.ext2. There is only one file with the .ext per directory, so no problem with that.

What I have done so far is:

find ./Parent -name "*.ext" -exec mv "{}" "{}.ext2" \;

And I get a bunch of The one to rename.ext.ext2, I am stuck about renaming them new name.ext2. If I just set it as the second argument of mv, it will move them into the Parent directory, and thus, each call to the mvfunction will overwrite the previous moved file.

Note: I couldn't make it work using the -exec bash -c '' argument. I tried something along the lines of:

find ./Parent -name "*.ext" -exec bash -c 'mv {} "$(dirname {})/new name.ext2"' \;

But I get some issue with the $() being expanded before {}

JoliG
  • 21

2 Answers2

1

You can use the -printf function of find to construct your commands:

find /tmp -name "*.ext" -printf "mv %p %h/new_name.ext"
mv /tmp/foo.ext /tmp/new_name.ext

When you surround the command with $(), the commands will be executed:

$(find /tmp -name "*.ext" -printf "mv %p %h/new_name.ext")
find /tmp -name "*.ext"
/tmp/new_name.ext

Update:

The above command does not correctly work on multiple files and did not use quotes values. Use the below command instead:

find /tmp -name \*.ext\*
/tmp/dir with space/bar.ext
/tmp/foo.ext

bash -x < <(find /tmp -name "*.ext" -printf "mv \"%p\" \"%h/new_name.ext2\"\n")
+ mv '/tmp/dir with space/bar.ext' '/tmp/dir with space/new_name.ext2'
+ mv /tmp/foo.ext /tmp/new_name.ext2

find /tmp -name \*.ext\*
/tmp/dir with space/new_name.ext2
/tmp/new_name.ext2
Lambert
  • 12,680
  • After you change new_name.ext to new name.ext2 (what the question asks for), this will output mv Parent/First Directory/The one to rename.ext Parent/First Directory/new name.ext2 — without any quotes.  How well do you suppose that's going to work as a command? – G-Man Says 'Reinstate Monica' Apr 28 '16 at 08:10
0

Use sed

for file in */*.ext; do
    ext2=`echo $file | sed 's/.ext/.ext2/'`
    mv $file $ext2
done
Peschke
  • 4,148
  • 1
    (1) For clarity, you might want to change \…`` to $(…) — see this, this, and this.  (2) You should always quote your shell variable references (e.g., "$file" and "$ext2") unless you have a good reason not to, and you’re sure you know what you’re doing.  (3) This renames The one to rename.ext to The one to rename.ext2 — but the question calls for it to be renamed to new name.ext2.  (4) A safer sed command would be s/\.ext$/.ext2/.  The one you are using would change mytextfile.ext to my.ext2file.ext. – G-Man Says 'Reinstate Monica' Apr 28 '16 at 08:01