1

Quite a few similar question are being asked. The error is probably staring at me in the face, but I just can't see it...

#!/bin/bash
declare -a files
shopt -s nullglob       
files=(*)
count=36   # offset

for oldfilename in "${files[@]}"; do
    (( count++ ))
#   newfilename=$(echo "$oldfilename" | sed -e "s/^[1-9][0-9]?\.jpg/Scount\.png/")
#   newfilename=${oldfilename/[1-9][0-9]?/Scount}
#   newfilename=${oldfilename/[1-9][0-9]?/"Scount"}
    newfilename=${oldfilename//[1-9][0-9]?/Scount}
    echo mv -fv /path1/to/"${oldfilename}" /path2/to/"${newfilename}"
done
exit 0

I have tried commented lines. I don't know the difference between / and // in newfilename=${oldfilename/[1-9][0-9]?/"Scount"}. o_0 ?

EDIT: Files represented by $oldfilename have the form 1.jpg to 99.jpg. Output files $newfilename are expected to have the form 37.png to 135.png (at least as far as the sed invocation goes).
Somehow files are not renamed and the dot in .jpg disappears. Why does this not work ?

10
  • 2
    Sample of input filenames and to what you expect them to be transformed please
    – roaima
    Jan 7 '16 at 22:13
  • 1
    Shouldn't that be $count instead of Scount? And, if so, you probably rather want $(printf "%02d" $count) to keep file names length constant (i.e. keep leading zeroes).
    – peterph
    Jan 7 '16 at 22:16
  • Is that an S in stead of a $ where you attempt to define newfilename?
    – joepd
    Jan 7 '16 at 22:18
  • 1
    Can you clarify what is happening? ("not working" is pretty vague.)  Also, please clarify what you want to happen.  It looks like you want to rename 1.jpg37.jpg, 2.jpg38.jpg, etc.  But what if you already have a file named 37.jpg or 38.jpg?  Does the sed version work when you replace Scount with $count?  (And do you really want to rename *.jpg files to *.png?)
    – Scott
    Jan 8 '16 at 1:17
  • Sorry to all for lacking in details. Somehow they're evident to me but understandably not to others. Here goes... @roaima : input file name have the form 1.jpg to 99.jpg. Output file names have the form 37.png to 135.png. @perterph: Thanks. It definitely should be $count instead of my nonsensical Scount. Leading zeroes for filenames starting with one or two digit numerals are already taken care of in the routine in which this snippet is inserted.
    – Cbhihe
    Jan 8 '16 at 7:48
2

I guess from your (commented out) sed command that you want to match and replace a regular expression: [1-9][0-9]?, meaning

  • a non-zero digit ([1-9]), followed by
  • zero or one digit(s) ([0-9]?)

which is a fairly common regex for an integer between 1 and 99 (with no leading zero).  However, ${parameter/pattern/string} doesn't use regexs, it uses pathname expansion patterns (a.k.a. wildcards).  So [1-9][0-9]? means

  • a non-zero digit ([1-9]), followed by
  • a digit ([0-9]), followed by
  • any character (?)

Still, it should have worked for the two-digit filenames, although it would consume the . and rename 10.jpg to 46jpg (without .).


Regarding the other part of your question, // replaces all occurrences of the pattern, while / replaces only the first.  For example,

$ i=cataract
$ echo "${i/a/X}"
cXtaract
$ echo "${i//a/X}"
cXtXrXct
2
  • Right on all counts, I corrected the snippet. Can you tell why I see // as well as / in pathname expansion bits on Stackexchange and elsewhere ? It seems that both syntaxes work ...
    – Cbhihe
    Jan 8 '16 at 8:19
  • 1
    // replaces all occurrences of the pattern; / replaces only the first. Jan 8 '16 at 8:24
1

If you have the Perl rename (sometimes called prename) you can do this:

rename -v 's!(\d+)(.*)\.jpg$!sprintf "%d%s.png", $1+36, $2!e' *.jpg

This takes each filename, splits off the leading digits, the rest of the filename component, and the trailing .jpg. It then adds 36 to the numeric part, adds on the remainder of the original filename, and replaces the suffix with .png.

Use rename -n ... to see what would happen with it changing anything, or remove the -v to have it run silently.

1
  • +1 Nice, elegant and certainly more concise than my implementation of C like bash.
    – Cbhihe
    Jan 8 '16 at 14:40

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.