4

In a directory structure which has multiple subfolders and files in it, some of the file names have the suffix _create (e.g. java1_create) and some of them with _bak (java2_bak).

I need to rename only the files with suffix _create as _bak, so that all the files should have the _bak suffix.

Is there any command or script to do this?

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
Ravi
  • 41

3 Answers3

3

On Linux, assuming that none of your file names have _create inside them (only at the end), you can use the rename utility from the util-linux package, which is installed on all non-embedded Linux systems. Call find to execute the command on all files in subdirectories recursively.

find -depth -exec rename _create _bak {} +

On Debian and derived distributions (Ubuntu, Mint, …) that ship a Perl script as rename, either call rename.ul instead of rename, or replace rename _create _bak by rename 's/_create$/_bak/'.

  • And then there's rename from Unicode::Tusssle, which is another Perl script, with different options (and arguably more powerful) than the Perl script you're referring to. Ah, the smell of Linux in the morning. ;) – lcd047 May 26 '15 at 04:31
2

This may be what you're after:

for file in $(find . -name "*_create"); do mv -i $file ${file%%_create}_bak; done

Be sure to test it before using it on real files.

Galik
  • 121
  • running the command returns illegal variable name. for file in $(find . -name "*_create"); do mv -i $file ${file%%_create}_bak; done Illegal variable name. – Ravi May 25 '15 at 10:03
  • @Ravi That's strange, it works for me. Are you using the bash shell or a different one? – Galik May 25 '15 at 10:23
  • Thanks Galic, changing to bash shell and running your command worked. Thanks a lot for the help – Ravi May 25 '15 at 11:17
1

On Debian, Ubuntu and derivatives, with the Perl rename, sometimes installed as prename:

#enable ** globbing
shopt -s globstar 
#use the rename utility
rename -n 's/_create$/_bak/' **_create 

Remove the -n (= --no-act) flag if it works as expected.


Note:

This is probably the shortest efficient way to do this, especially if you've got shotp -s globstar already on (I have it in my ~/.bashrc).

However, you could get:

-bash: /usr/bin/rename: Argument list too long

if the **_create expansion is over getconf ARG_MAX characters long (2097152 on my Linux box).

If that is case, you'll need to use find -print0 with xargs -0 (see lcd047's answer).

Petr Skocik
  • 28,816
  • Also, you really shouldn't add -n at the end of the command line. Too late for that, isn't it. – lcd047 May 25 '15 at 09:33
  • It doesn't matter where the -n is as long as it's before -- if -- is one of the arguments. It's at the end because that's where it's the easiest to delete from. – Petr Skocik May 25 '15 at 09:36
  • I had tried it and it worked (didn't do anything). We've obviously got different renames then. Mine's from the util-linux 2.20.1-5.1ubuntu20.4 package. It doesn't have the -0 option and the CL options don't have to come before arguments. – Petr Skocik May 25 '15 at 10:04
  • I moved the -n before the args to make it more portable. xargs -0 instead of rename -0 would make yours more portable too.s – Petr Skocik May 25 '15 at 10:08
  • 1
    The rename command that you used here is evidently not the one from util-linux, but the one from perl. – Gilles 'SO- stop being evil' May 25 '15 at 18:32
  • Yes, it links to prename. Apologies, I'm an idiot. Still it behaves the way I described it did (position of -n doesn't matter; no -0 option). Thanks, @Gilles. – Petr Skocik May 25 '15 at 18:42