Jump to content

shell script to rename files (advanced)


Recommended Posts

Hi,

 

I'm working (with some existing scripts and some home made stuff) on my own picture database

 

step 1: download pictures and give them a unique name

 

this is the script I have so far. Parts of it I understand, others I don't. It needs a lot of work but it works. If you understand it I'd be very pleased to know so I can improve it to make it work more efficient.

 

gphoto2 --camera "Canon EOS D30" --port usb: --get-all-files
mv IMG_* /home/jeroen/D30/nieuwzonderbackup
cd /home/jeroen/D30/nieuwzonderbackup

this part I wrote myself :D

I D/L my pics, move them and move the prompt with it

 

inputfile=`ls *.jpg *.JPG`
for imgname in $inputfile

I understand this

 

do
   if [ ! -f $imgname ]; then
       echo $imgname" not found."
       break
   fi

don't understand it but it doesn't look dangerous ;-)

 

    # Extracting image information
   info=`head $imgname| strings| grep 200 | grep :`
   newname=`echo $info|cut -d ' ' -f 1`"+"`echo $info|cut -d ' ' -f 2`".jpg"
   newname=`echo $newname|sed s/:/-/g`

I understand parts of it. from the header of the picture it takes a string,

it cuts parts away (I think, the "cut" is a mystery for me) and adds ".jpg" (found that out myself :-) )

the file gets renamed as follows: year-month-day+hour-minute-second.jpg

my problem is: my camera can take 3 pictures a second so I need more then this.

my problem is I don't understand the "cut" part so this is my "solution":

 

    #vermijden overschrijven trippel
   changefile=`ls *. jpg *.JPG`
   for changename in $changedfile
   do
       if [ $newname = $changename ]; then
info=`head $changename| strings| grep 200 | grep :`
       newname=`echo $info|cut -d ' ' -f 1`"+"`echo $info|cut -d ' ' -f 2`"c.jpg"
       newname=`echo $newname|sed s/:/-/g`
fi
   done
   #vermijden overschrijven dubbel
   changedfile=`ls *.jpg *.JPG`
   for changedname in $changedfile
   do
       if [ $newname = $changedname ]; then
       info=`head $changedname| strings| grep 200 | grep :`
       newname=`echo $info|cut -d ' ' -f 1`"+"`echo $info|cut -d ' ' -f 2`"b.jpg"
       newname=`echo $newname|sed s/:/-/g`
       fi
   done

quite NOT good programming I must say. I could use some help with reducing this to something simple. also, I want "image1.jpg", "image1b.jpg" and I had to swap the "b.jpg" and "c.jpg" in the cut commands to avoid "image1.jpg", "image1c.jpg". don't get it

 

    # Rename only if valid newname
   if [ "X$newname" != "X+" ]; then
       mv -i $imgname $newname
   fi
done
rm -rf .input

I get the "mv -i $imgname $newname". the rest is a mystery, especially the "rm -rf .input". is this ubiquitous?

 

So, I have some parts of which I think "can't I just delete this?" and some unelegant parts.

If anyone can help I'd be very happy.

If not, my script sucks but it works (afaik)

 

Jeroen

Link to comment
Share on other sites

do
   if [ ! -f $imgname ]; then
       echo $imgname" not found."
       break
   fi

 

Using these square brackets means the same as using the GNU command "test".

 

It's saying that if $imgname doesn't exist as a regular file, as opposed to a symlink or whatever, then carry out the instructions between the if statement., i would have thought though that the $imgname part was enclosed in the double quotes, but i am not certain on that.

 

About the rest of the script, you'll have to ask some others ;).

Link to comment
Share on other sites

I can help, but not with that "blind script", if you don't mind I would like to have some info, so please copy and paste the output of the follwing commands:

 

~$ ls *.jpg *.JPG

 

and

 

~$ head some_image.jpg (of course one of your camera images)

 

Then we can start talking. I'm sure it can be optimized a lot, for example instead of calling an external 'ls' command, you can do the same with shell builtins:

 

for imgname in *.jpg *.JPG; 
do 
      ...; 
done

 

is much more efficient than:

 

inputfile=`ls *.jpg *.JPG`
for imgname in $inputfile;
do
      ...;
done

 

All those messy 'extract image information' commands can be simplified a lot with awk or sed, not to talk about that second strange loop; but I need the input I asked you above (also it would be a good idea to paste the full working script)

 

see you :juggle:

Edited by aru
Link to comment
Share on other sites

aru, before I forget: thanks with the previous one. you're really good at this.

 

this is the result of "ls *.jpg *.JPG":

[jeroen@vlinder nieuwzonderbackup]$ ls *.jpg *.JPG
ls: *.jpg: No such file or directory
IMG_0898.JPG  IMG_0899.JPG  IMG_0900.JPG  IMG_0901.JPG  IMG_0902.JPG  IMG_0903.JPG

here there are only .JPG files but I have .jpg files as well.

 

and this is the result of "head IMG_0898.JPG"

[jeroen@vlinder nieuwzonderbackup]$ head IMG_0898.JPG
ÿØÿáþExifII*    z€?Ž(2ži‡²
                         CanonCanon EOS D30´´2004:01:13 22:20:02š‚P‚X'ˆd0210
‘‘8’
@’H’
`’h’p’  ’
’x|’F€†0 0100    À ֢Ƣ΢¢£2004:01:13 22:20:022004:01:13 22:20:02>÷
-²Ð
-²è2 :z‚Š¼
;È >?^
     U
      B~        vZj
–ª@0226ÿ2’bd2 ?608`™v
                  þþêë¯þþíퟟþþêíO¯þþë쟟þþíí¯þþìíŸþþêê¯þþë럟þþíí?þþíë_oþþ
ìê_þþëìŸþþíëŸþþìí¿þþïêþþï쀀IMG:EOS D30 JPEGFirmware Version 1.02Jeroen Men
tenss


ù|¦SR980100 À?Z(ô
                ´´ÿØÿÛ„

 

lots of crap but you'll see the date + time in it.

 

These are the files I want to rename according to YYYY-MM-DD+HH-MM-SS.jpg and with ...b.jpg and ...c.jpg if more then one pic on that time exists (these example pics have been taken to show that behaviour)

 

http://users.pandora.be/jeroenm/temp/IMG_0898.JPG

http://users.pandora.be/jeroenm/temp/IMG_0899.JPG

http://users.pandora.be/jeroenm/temp/IMG_0900.JPG

http://users.pandora.be/jeroenm/temp/IMG_0901.JPG

http://users.pandora.be/jeroenm/temp/IMG_0902.JPG

http://users.pandora.be/jeroenm/temp/IMG_0903.JPG

(about 90 kB/piece)

 

and http://users.pandora.be/jeroenm/temp/dlallesdaterename is the full script I have so far.

 

thank you!

Link to comment
Share on other sites

OK, this is what I've done (only the critical part of the script)

#! /bin/bash
# jeroenm.sh 
shopt -s extglob # for improved file pattern matching
for imgname in *.+(jpg|JPG); 
do
   newname="$(head $imgname|strings|sed -n '/[0-9]\{4\}\:.*/ {s/ /+/g; s/:/-/g; s/$/.jpg/; p}'|uniq)"
   # if there is already another file with the same name append an extension (b or c).
   # Just thinking a bit more this can be improved, but IMHO it will work OK:
   if ls ${newname%%.jpg}* &> /dev/null; then
       if   [ -f ${newname%%.jpg}b.jpg ]; then newname=${newname%%.jpg}c.jpg
       elif [ -f ${newname} ]; then newname=${newname%%.jpg}b.jpg
       fi
   fi
           
   mv ${imgname} ${newname}
done

 

 

This is what I get before and after running this script with your images:

 

~$ ls
IMG_0898.JPG  IMG_0899.JPG  IMG_0900.JPG  IMG_0901.JPG  IMG_0902.JPG  IMG_0903.JPG  jeroenm.sh*

~$ ./jeroenm.sh 

~$ ls
2004-01-13+22-20-02b.jpg  2004-01-13+22-20-03b.jpg  2004-01-13+22-20-03.jpg  jeroenm.sh*
2004-01-13+22-20-02.jpg   2004-01-13+22-20-03c.jpg  2004-01-13+22-20-04.jpg

~$

 

Probably you'll need to debug it and make it robust, but it works :jester:

If you have any doubts, please tell me (I enjoy these things :thumbs: )

Edited by aru
Link to comment
Share on other sites

Well, it looks brilliant!!!!

 

But it doesn't work :-(

I'm sure it's just a " " somewhere where there shouldn't be one but I don't understand anything of your script so I have no idea where to look for it.

OK, I can use the "man" but it'll take me ages while you'll probably see it right away.

 

Oh, about using "IMG*" instead of "*": I've got older files which have other names so I'll keep it to "*"

 

This is what I get (added some more files to check it out):

[jeroen@vlinder test]$ ls
IMG_0898.JPG  IMG_0903.JPG  IMG_0908.JPG  IMG_0913.JPG  IMG_0918.JPG
IMG_0899.JPG  IMG_0904.JPG  IMG_0909.JPG  IMG_0914.JPG  scriptaru*
IMG_0900.JPG  IMG_0905.JPG  IMG_0910.JPG  IMG_0915.JPG
IMG_0901.JPG  IMG_0906.JPG  IMG_0911.JPG  IMG_0916.JPG
IMG_0902.JPG  IMG_0907.JPG  IMG_0912.JPG  IMG_0917.JPG
[jeroen@vlinder test]$ ./scriptaru
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
sed: -e expression #1, char 49: Extra characters after command
[jeroen@vlinder test]$ ls
b.jpg  c.jpg  scriptaru*
[jeroen@vlinder test]$

Link to comment
Share on other sites

this is the script as I used it:

#! /bin/bash
# made by arusabal (www.mandrakeusers.com)
shopt -s extglob # for improved file pattern matching
for imgname in *.+(jpg|JPG);
do
  newname="$(head $imgname|strings|sed -n '/[0-9]\{4\}\:.*/ {s/ /+/g; s/:/-/g; s/$/.jpg/; p}'|uniq)"
  # if there is already another file with the same name append an extension (b or c).
  # Just thinking a bit more this can be improved, but IMHO it will work OK:
  if ls ${newname%%.jpg}* &> /dev/null; then
      if   [ -f ${newname%%.jpg}b.jpg ]; then newname=${newname%%.jpg}c.jpg
      elif [ -f ${newname} ]; then newname=${newname%%.jpg}b.jpg
      fi
  fi

  mv ${imgname} ${newname}
done

 

I only changed a comment and renamed the script. thant can't be it, can it?

Edited by JeroenM
Link to comment
Share on other sites

I don't know what's the problem man, this is a test copying and pasting from your post:

 

 ~$ head IMG_0898.JPG|strings|sed -n '/[0-9]\{4\}\:.*/ {s/ /+/g; s/:/-/g; s/$/.jpg/; p}'|uniq
2004-01-13+22-20-02.jpg
~$

It works fine for me.

 

Play a bit with that expression in your console to see if you can find out what is wrong in your system. I suggest you to test step by step the command, ie:

 

~$ head IMG_0898.JPG|strings|sed -n '/[0-9]\{4\}\:.*/ {p}'
2004:01:13 22:20:02
2004:01:13 22:20:02
2004:01:13 22:20:02
~$ head IMG_0898.JPG|strings|sed -n '/[0-9]\{4\}\:.*/ {s/ /+/g; p}'
2004:01:13+22:20:02
2004:01:13+22:20:02
2004:01:13+22:20:02
~$ head IMG_0898.JPG|strings|sed -n '/[0-9]\{4\}\:.*/ {s/ /+/g; s/:/-/g; p}'
2004-01-13+22-20-02
2004-01-13+22-20-02
2004-01-13+22-20-02
~$ head IMG_0898.JPG|strings|sed -n '/[0-9]\{4\}\:.*/ {s/ /+/g; s/:/-/g; s/$/.jpg/; p}'
2004-01-13+22-20-02.jpg
2004-01-13+22-20-02.jpg
2004-01-13+22-20-02.jpg
~$ head IMG_0898.JPG|strings|sed -n '/[0-9]\{4\}\:.*/ {s/ /+/g; s/:/-/g; s/$/.jpg/; p}'|uniq
2004-01-13+22-20-02.jpg
~$

 

here it works like charm as you can see

 

... I can only suggest to add a ';' after the 'p' in the sed command, since there where that 'char 49' is placed (but I insist in that here it works fine (tested on debian and mandrake))

Edited by aru
Link to comment
Share on other sites

I don't get the errors, but I, too, only get two images renamed to b.jpg and c.jpg

Maybe it has something to do with bad headers in the .jpg files?

are you using the files provided by JeroenM? The script only works for those type of files since it looks for particular strings in their heads

Link to comment
Share on other sites

... I can only suggest to add a ';' after the 'p' in the sed command, since there where that 'char 49' is placed (but I insist in that here it works fine (tested on debian and mandrake))

tadaaaaaa!

adding the ; works.

 

[jeroen@vlinder test]$ head IMG_0899.JPG|strings|sed -n '/[0-9]\{4\}\:.*/ {s/ /+/g; s/:/-/g; s/$/.jpg/; p}'|uniq
sed: -e expression #1, char 49: Extra characters after command
[jeroen@vlinder test]$ head IMG_0899.JPG|strings|sed -n '/[0-9]\{4\}\:.*/ {s/ /+/g; s/:/-/g; s/$/.jpg/; p;}'|uniq
2004-01-13+22-20-02.jpg
[jeroen@vlinder test]$

 

perfect!

thanks!

 

I'll be looking for a new challenge for you right away ;-) :thumbs:

Link to comment
Share on other sites

oh, what if I have a file without a header (like after using Gimp)?

 

hmm, I'll quickly test it and let you know.

 

edit:

OK, I found out.

don't use the script for that ;-)

and don't use the script on files which have been renamed already ;-)

that's OK. I'll just have to take care when I use the script.

thanks

 

this is what I get after adding 2 files without a header and repeat the script several times (just in case you have a real urge to "fix" it):

[jeroen@vlinder test2]$ ls
2004-01-13+22-20-03bresave.jpg       IMG_0899.JPG  IMG_0903.JPG  IMG_0907.JPG  IMG_0911.JPG  IMG_0915.JPG
2004-01-13+22-20-03bresaveklein.jpg  IMG_0900.JPG  IMG_0904.JPG  IMG_0908.JPG  IMG_0912.JPG  IMG_0916.JPG
daterenamearusabal*                  IMG_0901.JPG  IMG_0905.JPG  IMG_0909.JPG  IMG_0913.JPG  IMG_0917.JPG
IMG_0898.JPG                         IMG_0902.JPG  IMG_0906.JPG  IMG_0910.JPG  IMG_0914.JPG  IMG_0918.JPG
[jeroen@vlinder test2]$ ./daterenamearusabal
[jeroen@vlinder test2]$ ls
2004-01-13+22-20-02b.jpg  2004-01-14+22-09-46b.jpg  2004-01-14+22-09-49.jpg   2004-01-14+22-09-52.jpg
2004-01-13+22-20-02.jpg   2004-01-14+22-09-46c.jpg  2004-01-14+22-09-50b.jpg  2004-01-14+22-09-53.jpg
2004-01-13+22-20-03b.jpg  2004-01-14+22-09-46.jpg   2004-01-14+22-09-50.jpg   2004-01-14+22-09-54.jpg
2004-01-13+22-20-03c.jpg  2004-01-14+22-09-47.jpg   2004-01-14+22-09-51b.jpg  b.jpg
2004-01-13+22-20-03.jpg   2004-01-14+22-09-48b.jpg  2004-01-14+22-09-51c.jpg  c.jpg
2004-01-13+22-20-04.jpg   2004-01-14+22-09-48.jpg   2004-01-14+22-09-51.jpg   daterenamearusabal*
[jeroen@vlinder test2]$ ./daterenamearusabal
[jeroen@vlinder test2]$ ls
2004-01-13+22-20-02b.jpg  2004-01-14+22-09-46b.jpg  2004-01-14+22-09-49b.jpg  2004-01-14+22-09-52b.jpg
2004-01-13+22-20-02c.jpg  2004-01-14+22-09-46c.jpg  2004-01-14+22-09-50b.jpg  2004-01-14+22-09-53b.jpg
2004-01-13+22-20-03b.jpg  2004-01-14+22-09-47b.jpg  2004-01-14+22-09-50c.jpg  2004-01-14+22-09-54b.jpg
2004-01-13+22-20-03c.jpg  2004-01-14+22-09-48b.jpg  2004-01-14+22-09-51b.jpg  b.jpg
2004-01-13+22-20-04b.jpg  2004-01-14+22-09-48c.jpg  2004-01-14+22-09-51c.jpg  daterenamearusabal*
[jeroen@vlinder test2]$ ./daterenamearusabal
[jeroen@vlinder test2]$ ls
2004-01-13+22-20-02.jpg   2004-01-14+22-09-47c.jpg  2004-01-14+22-09-51.jpg   c.jpg
2004-01-13+22-20-03.jpg   2004-01-14+22-09-48.jpg   2004-01-14+22-09-52c.jpg  daterenamearusabal*
2004-01-13+22-20-04c.jpg  2004-01-14+22-09-49c.jpg  2004-01-14+22-09-53c.jpg
2004-01-14+22-09-46.jpg   2004-01-14+22-09-50.jpg   2004-01-14+22-09-54c.jpg
[jeroen@vlinder test2]$

Edited by JeroenM
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...