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?

4 Answers 4

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 [email protected]
$

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
$
4
  • 3
    Note that the perl rename predates the dumb rename found in util-linux that you call plain old rename. It even predates Linux. Jul 27, 2018 at 14:49
  • @StéphaneChazelas what do you mean by "It even predates Linux". I imagine it is some sort of methaphore/euphemism, but I don't get it.
    – onlycparra
    Jan 17, 2022 at 18:27
  • @onlycparra, first release of Linux is from 1991. The rename example script was added to perl in 3.0 in 1990, which is what I meant by "it predates Linux". Jan 17, 2022 at 20:58
  • my brain, which is still learning English took me the wrong way one more time. Somehow I related "predates" with "predator"... On the plus side, new word + potential jokes for the future.
    – onlycparra
    Jan 17, 2022 at 22:53
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).

2
  • Or zmv's: zmv '*.JPG' '${(L)f}' Jul 27, 2018 at 15:00
  • 1
    A simpler version of rename 's/.*/\L$&/' *.JPG would be rename '$_ = lc' *.JPG
    – hobbs
    Jul 27, 2018 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.

0
1

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

rename 'IMG' 'img' * ; rename 'JPG' 'jpg' *
1
  • 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. Aug 1, 2018 at 6:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .