0

I'd like to recursively rename all repository and file names under a specific directory that contain a given pattern.

I think I found a potential solution here with the following command:

find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+

However it seems like I don't have the right rename command.

I installed Perl Rename package but I still don't have the Perl based rename command available. What can I do to be able to use this command?

Is there an alternative solution to this rename solution?

Let's say I have the following repositories and files:

BOOK1/
BOOK1/BOOK1_summary.txt
BOOK1/BOOK1_chapter1/BOOK1_chapter1.txt

I'd like to rename all occurrences of BOOK1 by BOOK-01 in repository and file names:

BOOK1-01/
BOOK1-01/BOOK1-01_summary.txt
BOOK1-01/BOOK1-01_chapter1/BOOK1-01_chapter1.txt
thbtmntgn
  • 151
  • 2
  • 8

1 Answers1

1

You could use the rename PERL utility which could be downloaded from this link.

find  BOOK1 -depth -exec rename -n 's/^(.*)(BOOK1)(.*)$/$1BOOK1-01$3/' {} \;

Dry-run output

rename(BOOK1/BOOK1_summary.txt, BOOK1/BOOK1-01_summary.txt)
rename(BOOK1/BOOK1_chapter1/BOOK1_chapter1.txt, BOOK1/BOOK1_chapter1/BOOK1-01_chapter1.txt)
rename(BOOK1/BOOK1_chapter1, BOOK1/BOOK1-01_chapter1)
rename(BOOK1, BOOK1-01)

Remove the -n option from rename once you verify the dry-run result..

Actual Output

 ls -R BOOK1-01/ # Used a recursive listing here.
BOOK1-01/:
BOOK1-01_chapter1  BOOK1-01_summary.txt

BOOK1-01/BOOK1-01_chapter1:
BOOK1-01_chapter1.txt

Note : The -depth option with find is the key here. The find manpage says it process each directory's contents before the directory itself.

sjsam
  • 21,411
  • 5
  • 55
  • 102
  • the 'rename' command does not have the -n option on my side. I tried without it directly and it gave me the following error message: 'rename: not enough arguments' Also, I saw that you used '3/s' at the end of the 'rename' command. I think it's because there are 3 occurrences max per path on my example right? If there is more, can I use '/g' instead? – thbtmntgn Apr 17 '19 at 15:12
  • 1
    It is not `3/s` It is `$3`. Please note that I have used three `(stuff)`. Anything inside the parenthesis `()` can be reused using `$1` for the first match, `$2` for the second match and so. The global option `g` should NOT be used here as it is detrimental to this solution. – sjsam Apr 17 '19 at 15:30
  • 1
    @thbtmntgn I have made a small change in the `find` command. Please try the new one. If you don't have the `-n` option search the man-page for `rename` and look for the option that gives you the `dry-run` option. There was a rogue `s` at the end of `rename` script which I removed. Try the new one and let me know if you got any luck with it :) – sjsam Apr 17 '19 at 15:38
  • I re-run your command and got the "rename: not enough arguments" error. The 'rename' command I have does not seems to have a dry-run option. Only four options: -v/--verbose --> explain what is being done, -s/--symlink --> act on symlink target, -h/--help --> display this help and exit, -V/--version --> output version information and exit – thbtmntgn Apr 17 '19 at 15:41
  • /usr/bin/rename: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.35 – thbtmntgn Apr 17 '19 at 15:47
  • rename from util-linux 2.23.2 – thbtmntgn Apr 17 '19 at 15:48
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/191992/discussion-between-thbtmntgn-and-sjsam). – thbtmntgn Apr 17 '19 at 15:49
  • 1
    Installing 'File::Rename' Perl package with 'cpan' solved the problem for me. It created the 'rename' executable in '/usr/local/bin' – thbtmntgn Apr 17 '19 at 17:32