Unix Bash rename files using a regex

4

3

I would like to rename all files from a folder using a regex(add a name to the end of name) and move to another folder.

It my opinion, it should be looking like this:

mv -v ./images/*.png ./test/*test.png, but it is not working.

Can anyone suggest me a solution?

mxg

Posted 2009-12-25T14:37:27.970

Reputation: 310

Answers

6

I also like the rename command that John T posted, but it's not available on all systems. This should work everywhere:

for i in *.png; do mv -v $i `basename $i .png`.test.png; done

Hal Pomeranz

Posted 2009-12-25T14:37:27.970

Reputation: 76

here's what it returns:

usage: mv [-f | -i | -n] [-v] source target mv [-f | -i | -n] [-v] source ... directory – mxg – 2009-12-25T15:00:48.010

2Worked for me: perhaps you should try quoting instances of your $i: "$i" – Jeremy L – 2009-12-25T15:48:51.723

It works also for mac. – mxg – 2009-12-25T17:36:27.013

This is, more or less, the standard UNIX way of doing the task, as all you need is a Bourne shell. The perl method is newfangled. Cool, but new-fangled. – pcapademic – 2009-12-25T20:27:40.067

@EricJLN: it's only "new-fangled" compared to UNIX itself -- Perl's been around for more than two decades now. (by comparison, the Bourne shell's only a single decade older; bash is the same age as Perl.) the Perl Cookbook was published in 1998 and includes a simple version of the same script; it's certainly older than that. – quack quixote – 2009-12-25T21:01:31.327

7

There's a handy perl file-renaming script that gets installed with the main Perl package on Debian-based systems (including Ubuntu). It's usually named rename, but sometimes is called prename (Perl rename). Use like this:

rename expr file1 file2 file3

The command uses Perl to evaluate expr for each file argument, and it renames each file to the output of the expr evalutation. So, for simple regex replacements like your example:

rename 's(images/(.*)\.png$)(test/$1.test.png)' ./images/*

# here's the expression:
# s()()   -- just like s/// (but i don't need to escape the / in the filename)
#   match regex:  images/(.*)\.png$     -- match filenames of the form images/*.png
#   replace:      test/$1.test.png     -- turn them into test/*.test.png

If files don't match the expression (for example, non-PNG files), the substitution won't do anything and their filenames won't be changed.

quack quixote

Posted 2009-12-25T14:37:27.970

Reputation: 37 382

3

You can use rename which accepts regular expressions or this basic 3 argument syntax:

rename .png .test.png *.png
  • The first argument is what to replace in the filename
  • The second argument is what to replace it with
  • The third argument is what files to perform the operation on, in this case, all pngs.

John T

Posted 2009-12-25T14:37:27.970

Reputation: 149 037

is this the same as the perl rename i describe, or something else? i'm not familiar with the syntax you describe. – quack quixote – 2009-12-25T17:22:15.463

I don't think so. This one is a binary. See here: http://linux.die.net/man/1/rename and here: http://pastebin.ca/1726871 .

– John T – 2009-12-25T18:34:28.207

thx, that's interesting. might be why the rename i mentioned gets installed to /usr/bin/prename and then symlinked to /usr/bin/rename. – quack quixote – 2009-12-25T18:38:26.793