1

I'm using a script to make backups of files, and to avoid overwriting files I've used cp --backup. Which leaves me with a number of files that look like example.mov.orig and test.mov.orig. I cannot figure out regular expressions at all, and was wondering if anyone knows of a way to cut off the .orig and append _1 to the base name using rename.

Essentially the result I'm looking for is command that would change example.mov.orig to become example_1.mov that I could use in conjunction with find /example/ -name *.*.orig

Output from rename --version is util-linux-ng 2.18

  • 1
    What distribution are you using? There are two common rename implementations out there and they have very different format. We need to know which one you have to answer correctly. – terdon Oct 20 '15 at 11:52
  • Ah sorry, I'm using Puppy Linux – Richard Good Oct 20 '15 at 12:02
  • That should be perl-rename then. OK, please [edit] your question and post the output of rename.ul --version. That will either priutn a usage message (which includes the information we need) or version information. Either way, please add the output to your question. – terdon Oct 20 '15 at 12:05
  • @terdon, ITYM rename --version. rename.ul is always going to be the util-linux rename, and prename is always going to be the perl rename. rename could be either. on a debian-based system, it's controlled by the alternatives system - update-alternatives --display rename – cas Oct 20 '15 at 12:13
  • @cas Debian-based systems default to prename, yes, but as I recall, the RedHat world defaults to rename.ul. I don't know if all distros will have both installed by default. – terdon Oct 20 '15 at 12:56

2 Answers2

2

The rename command you need is:

  • If you're using rename from util-linux:

    rename . _1. *.orig && rename .orig '' *.orig
    

    The first will replace the first occurence of . with _1. for all files ending in .orig. The second will remove the .orig from the file names.

  • If you're using perl-rename (default on Debian-based systems), things are simpler since it uses Perl Compatible Regular Expressions so can do everything in one step:

    rename 's/(\..*)\.orig/_1$1/' *orig
    

    Since this version uses The regex will match the first . (\., the . needs to be escaped since ti means "any character" whan not escaped), then everything (.*) until .orig. Because the first pattern is inside parentheses, it is "captured" and can later be referred to as $1. Therefore, the replacement will replace anything matched previously with a _1 and the captured pattern (the first extension) and it will simultaneously remove the .orig.

You can combine the commands with find as follows:

find /example -name '*.orig' -exec rename . _1. {} +
find /example -name '*.orig' -exec rename .orig '' {} +

Or:

find /example -name '*.orig' -exec rename 's/(\..*)\.orig/_1$1/'

You don't even need find for this. If all your files are in the same directory, you can use the commands above directly, or, to make it recursive (assuming you are using bash):

shopt -s globstar                               ## make ** recurse into subdirectories
rename.ul . _1. **.orig && rename.ul .orig '' **.orig  ## util-linux
rename  's/(\..*)\.orig/_1$1/' **orig                  ## perl rename

In fact, strictly speaking, you don't even need rename. You can do everything in the shell (see here for an explanation of the shell's string manipulation abilities):

for file in **/*.orig; do 
    newname="${file%%.*}_1.${file#*.}"
    mv "$file" "${newname/.orig/}"
done

Finally, a note on globs (-name uses a glob, not a regular expression). The *.*.orig is Windows glob syntax for "anything ending in .orig". The equivalent and what you should use with your find is *.orig. The * alone matches anything, using *.*.orig will only match file names with two extensions, the last of which is .orig.

terdon
  • 242,166
1

Firstly you should check what version of rename have installed in your system

readlink -e $(which rename)

So for prename (default in .deb hosts):

prename 's/(\.[^.]*)\.orig/_1$1/' *.*.orig

and for rename.ul from util-linux package

rename.ul \. _1\. *.*.orig     #add «_1» into file name
rename.ul \.orig '' *.*.orig   #remove «.orig» extention
Costas
  • 14,916