8

I'm trying to rename a few images:

IMG_1.JPG
IMG_2.JPG
IMG_3.JPG

I want to replace IMG with img and .JPG with .jpg - I know how to do the second part:

$ rename 's/\.JPG$/\.jpg/' *.JPG

My problem is that I can't seem to mv IMG_.JPG to img_.jpg - I know you can pass multiple patterns to rename, but I can't seem to use the existing filename with an amended lowercase value.

How do I go about this?

10

Maybe you need to be using the perl rename command. On my CentOS box, it's called 'prename'.

$ ls
IMG_1.JPG  IMG_2.JPG  IMG_3.JPG
$ prename 's/^IMG/img/;s/\.JPG$/\.jpg/' *JPG
$ ls
img_1.jpg  img_2.jpg  img_3.jpg
$

$ prename -h
Usage: prename [OPTION]... PERLEXPR FILE...
Rename FILE(s) using PERLEXPR on each filename.

  -b, --backup                  make backup before removal
  -B, --prefix=SUFFIX           set backup filename prefix
  -f, --force                   remove existing destinations, never prompt
  -i, --interactive             prompt before overwrite
  -l, --link-only               link file instead of reame
  -n, --just-print, --dry-run   don't rename, implies --verbose
  -v, --verbose                 explain what is being done
  -V, --version-control=METHOD  override the usual version control
  -Y, --basename-prefix=PREFIX  set backup filename basename prefix
  -z, -S, --suffix=SUFFIX       set backup filename suffix
      --help                    display this help and exit
      --version                 output version information and exit

The backup suffix is ~, unless set with SIMPLE_BACKUP_SUFFIX.  The
version control may be set with VERSION_CONTROL, values are:

  numbered, t     make numbered backups
  existing, nil   numbered if numbered backups exist, simple otherwise
  simple, never   always make simple backups

Report bugs to pederst@cpan.org
$

If you want to use the dumb rename command from util-linux (sometimes called rename.ul), perhaps needs doing in two steps, e.g.

$ ls
IMG_1.JPG  IMG_2.JPG  IMG_3.JPG
$ rename IMG img *JPG
$ rename JPG jpg *JPG
$ ls
img_1.jpg  img_2.jpg  img_3.jpg
$
  • 3
    Note that the perl rename predates the dumb rename found in util-linux that you call plain old rename. It even predates Linux. – Stéphane Chazelas Jul 27 '18 at 14:49
6

To answer you question in the generic,

rename multiple files with 2 conditions/replacements in one line?

you would typically use capture groups, referring to them in the replacement expression using their corresponding backreferences. For example

$ rename -n 's/^(.*)_(.*)\.JPG$/\L$1_$2.jpg/' *.JPG
rename(IMG_2.JPG, img_2.jpg)
rename(IMG_3.JPG, img_3.jpg)

However, in this particular case, it would be simpler to just apply the lowercase modifier \L to the whole name:

$ rename -n 's/.*/\L$&/' *.JPG
rename(IMG_2.JPG, img_2.jpg)
rename(IMG_3.JPG, img_3.jpg)

Another alternative, using mmv

$ mmv -n '*.JPG' '#l1.jpg'
IMG_2.JPG -> img_2.jpg
IMG_3.JPG -> img_3.jpg

(remove the -n to actually perform the rename).

  • Or zmv's: zmv '*.JPG' '${(L)f}' – Stéphane Chazelas Jul 27 '18 at 15:00
  • 1
    A simpler version of rename 's/.*/\L$&/' *.JPG would be rename '$_ = lc' *.JPG – hobbs Jul 27 '18 at 17:04
2

Using mv:

sh compatible:

for file in *.JPG; do mv "$file" "$(echo "$file" | tr '[:upper:]' '[:lower:]')"; done

bash (Thanks steeldriver):

for file in *.JPG; do mv "$file" "${file,,}"; done

This will loop through all .JPG files in the current directory and rename them to the same name with all uppercase characters converted to lowercase characters.

1

The simplest way and based on the man page that does not cover a regular expression:

rename 'IMG' 'img' * ; rename 'JPG' 'jpg' *
  • IMHO, a simple answer like this achieves what the heavy hitting occasionally fails to. No malice towards seasoned programmers, but since the question seems to be from a newbie, simplicity needs to be encouraged. – Hopping Bunny Aug 1 '18 at 6:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.