0

I am trying to rename the following directory structure

Tests Directory
├── Test1 Directory
│   ├── 2 - 1. Data
│   ├── 3 - 2. Data
│   ├── 4 - 3. Data
│   ├── 5 - 4. Data
│   ├── 6 - 5. Data
├── Test2 Directory
│   ├── 2 - 1. Data
│   ├── 3 - 2. Data
│   ├── 4 - 3. Data
│   ├── 5 - 4. Data
├── Test3 Directory
│   ├── 2 - 1. Data
│   ├── 3 - 2. Data
│   ├── 4 - 3. Data
│   ├── 5 - 4. Data
│   ├── 6 - 5. Data

With

Tests Directory
├── Test1 Directory
│   ├── 1. Data
│   ├── 2. Data
│   ├── 3. Data
│   ├── 4. Data
│   ├── 5. Data
├── Test2 Directory
│   ├── 1. Data
│   ├── 2. Data
│   ├── 3. Data
│   ├── 4. Data
├── Test3 Directory
│   ├── 1. Data
│   ├── 2. Data
│   ├── 3. Data
│   ├── 4. Data
│   ├── 5. Data

If I run fd -t d -x rename 's/^(\d+ -)\s(\d+.)/$1/' in Test1, Test2 & Test3 - it works.

However, I want to use the command in Test so that I do not have to run the command in each directory.

I have tried

% find . -type d -exec rename 's/^(\d+ -)\s(\d+.)/$1/' {} \;
% find . -type d -exec rename 's/^(\d+ -)\s(\d+.)/$1/' {} ";"

Nothing is working. What can I do?

Adding more details.

% find . -maxdepth 2 -type d -execdir echo {} \;
./.
./Test1 Directory
./2 - 1. Data
./3 - 2. Data
./4 - 3. Data
./5 - 4. Data
./6 - 5. Data
./Test2 Directory
./2 - 1. Data
./3 - 2. Data
./4 - 3. Data
./5 - 4. Data
./Test3 Directory
./2 - 1. Data
./3 - 2. Data
./4 - 3. Data
./5 - 4. Data
./6 - 5. Data

PS, The directory names have spaces.

Ahmad Ismail
  • 2,478
  • 1
  • 22
  • 47

1 Answers1

0

There's a couple of problems with your find attempts, but you're on the right path.

  1. Limit the depth of find recursion so the renamed directories are not themselves searched. use the -maxdepth option for that, and note that it must come before the tests but after the root (i.e. between . and -type d).

  2. Because your rename command assumes you're in the directory directly above the one you're renaming, you need to use the execdir action instead of exec. Like most of the other actions, exec is done from the find top directory (i.e. . in your case), and it is passed the entire path from the top to the "found" entry, not just the bare filename (i.e. in your case, exec is passed something like ./Test1/2. - 1. Data). execdir fixes both of these issues.

q.undertow
  • 518
  • 2
  • 10
  • Should I use `find . -maxdepth 1 -type d -execdir rename 's/^(\d+ -)\s(\d+.)/$1/' {} \;` – Ahmad Ismail Nov 07 '20 at 20:01
  • the directory names have spaces. – Ahmad Ismail Nov 07 '20 at 20:05
  • I think you need -maxdepth 2 (it counts from 1). If it doesn't work please substitute rename with an action that prints the current directory _and_ the entry being acted on, for debugging. – q.undertow Nov 07 '20 at 20:05
  • 1
    If your regexp is right (and I have not tested it), spaces should not matter. That's the advantage of using `find -exec` or `find -execdir` over the bad old `xargs` way. – q.undertow Nov 07 '20 at 20:07
  • It is still not working. Added `find . -maxdepth 2 -type d -execdir echo {} \;` output in the question. – Ahmad Ismail Nov 07 '20 at 20:17
  • Ok sorry I guess I overlooked that even with `execdir` you still get the leading dot-slash in the names. – q.undertow Nov 12 '20 at 23:41
  • The solution that is working for me is `find . -type d -execdir rename 's!^\./(\d+ -)\s(\d+\.)!$2!' {} +` – Ahmad Ismail Nov 13 '20 at 11:12