skip to Main Content

I’m trying to rename a large amount of files within several directories recursively. I’m on Ubuntu Linux.

Last night I made a mistake leading to all of my files and directories being renamed with the prefix, "L" like e.g.
folder1/file1.img -> Lfolder1/Lfile1.im
folder2/file2.img -> Lfolder2/Lfile2.img
folder3/file3.img -> Lfolder3/Lfile3.img

I’m using the Perl rename function:

rename 's/^L//' *

This works on it’s own, within 1 directory, but pairing it with "find" and "exec" to work recursively doesn’t work, like this:

find . -depth -exec rename 's/^L//' {} +

I’ve tried using "-execdir" and playing around with the syntax while not committing any changes but I can’t get it to work.

On it’s own this returns the full recursive list of directories as well which is very weird.

find . 

This works on 1 directory, but not the subdirectories, see result effect:

rename 's/^L//' * 

Lfolder1/Lfile1.img -> folder1/Lfile1.img
Lfolder2/Lfile2.img -> folder2/Lfile2.img
Lfolder3/Lfile3.img -> folder3/Lfile3.img

I have tried this, and it also doesn’t return anything. Inserting "echo" after the exec command returns the list of files, though, but it does not seem to be passing them to the rename command:

find . -depth -exec rename 's/^L//' {} +

Does anyone know how to target directories recursively, and fix this issue? I’m looking to, after I’ve fixed my mistake, rename all of the files and directories to lower-case.

2

Answers


  1. The filenames, as you can see from using echo as the -execdir parameter, contain the leading ./, so ^L doesn’t really match any of them. You need to switch to /L instead, and to avoid the leaning toothpick syndrome, switch to a different delimiter.

    find . -depth -execdir rename 's=/L=/=' {} ;
    

    The -depth is still needed, otherwise the directories are renamed before their contents and find isn’t able to enter them.

    Login or Signup to reply.
  2. You pass Lfolder1/Lfile1.img first, intending to have it renamed to Lfolder1/file1.img, but that’s not the L that’s matched!

    Solutions:

    find . -depth -execdir rename 's/^L//' {} ;
    
    find . -depth -exec rename -d 's/^L//' {} +
    

    The latter should be faster (fewer launches of rename). -d causes the directory to be stripped before the provided code is executed, and readded afterwards.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search