change file extension from root and subdirectories

Hello, my first post!
I'd appreciate help with this script, I'm new to this.

I have a media directory where I want to batch convert image file names from .img to .iso.

I've tried but get:
$ ./img2iso2.sh
./img2iso2.sh: line 13: syntax error: unexpected end of file :frowning:

This is my unfinished script:

#!/bin/bash

# Set the video directory here
VIDEO_ROOT_DIRECTORY="/Users/astrid/NFS/scripts/img2iso/";

# Check if the directory exist or not
if [ -d "$VIDEO_ROOT_DIRECTORY" ]; then
	cd $VIDEO_ROOT_DIRECTORY
else
	print "ERROR: Unable to reach directory - or it does not exist!";
fi

for imgfile do 
    	case $imgfile *.img
            	do mv $imgfile.img $imgfile.iso;
               	done
          print "img-files renamed to iso";
    	esac
done

exit 0

I assume this doesn't check subdirectories, even though I'd like it to. Maybe a combination of find, grep and sed should be used instead? These commands seems to work marvels in almost any situation.

Also, I'd think it would be smart to include some sort of check:
if there is a file called image.iso and one called image.img in the same (sub)directory; I'd like to change the name of that .img file to image-1.iso. But I don't even know where to start with this check!

If I understand the error message there's a problem with quoting? I've made so many trials that I can't remember where I started anymore.

Any help is greatly appreciated.

EDIT:
Searching the forum I found a better way to do the replacement of the file extension (here), but I wasn't so lucky with the subdirs.

This should work for you:

#!/bin/bash

VIDEO_ROOT_DIRECTORY="/Users/astrid/NFS/scripts/img2iso"

for imgfile in `find "$VIDEO_ROOT_DIRECTORY" -name "*.img" -type f`
do
   n=0
   exit=""
   suffix=""

   while [ ! "$exit" ]
   do
      newname=`echo "$imgfile" | sed "s/\.img$/$suffix\.iso/"`
      if [ ! -f "$newname" ]
      then
         mv "$imgfile" "$newname"
         exit="y"
      else
         n="$((n+1))"
         suffix="-$n"
      fi
   done
done

Thank you for the quick reply, robotronic!

But I am sorry to say that I could not get it to work.

The script runs and then I get prompt again but there is no indication if it goes wrong somewhere, I even tried to change the video root to a dummy directory to invoke some feedback but to no avail. :confused:

I've used "touch" to make some dummy files in the specified directory and subdirectories: some with the same name but different extension (.img and .iso, obviously, and some other just to see if they are affected), and some files with different permissions (chmod 777 on most).

But not one changed the extension.

The script itself is located in one directory level above the "media root" (as set in the script).

$ ls -l img2iso
total 0
-rwxrwxrwx    1 astrid  619956085    0 Feb 15 13:01 dummy.img
-rw-r--r--   1 astrid  619956085    0 Feb 15 21:50 dummy.iso
-rwxrwxrwx    1 astrid  619956085    0 Feb 15 13:01 example.img
-rw-r--r--    1 astrid  619956085    0 Feb 15 21:35 example_no_permission.img
-rwxrwxrwx    1 astrid  619956085    0 Feb 15 13:01 image.img
-rw-r--r--    1 astrid  619956085    0 Feb 15 13:01 isoimg.iso
drwxr-xr-x    2 astrid  619956085   68 Feb 15 12:53 level1a
drwxr-xr-x    9 astrid  619956085  306 Feb 15 13:00 level1b

Very strange, I've tested the script with some dummy files and it works on my linux box.

Try inserting some echo commands in the script and try to re-run it:

#!/bin/bash

# Set the video directory here
VIDEO_ROOT_DIRECTORY="/Users/astrid/NFS/scripts/img2iso"

for imgfile in `find "$VIDEO_ROOT_DIRECTORY" -name "*.img" -type f`
do
   echo "Processing IMGFILE <$imgfile>"
   n=0
   exit=""
   suffix=""

   while [ ! "$exit" ]
   do
      newname=`echo "$imgfile" | sed "s/\.img$/$suffix\.iso/"`
      if [ ! -f "$newname" ]
      then
         echo "NEW NAME OK! Renaming to <$newname>"
         mv "$imgfile" "$newname"
         exit="y"
      else
         echo "NEW NAME <$newname> already exists! Incrementing suffix"
         n="$((n+1))"
         suffix="-$n"
      fi
   done

You can also run the script with "sh -x img2iso.sh" to trace the execution.

$ ./img2iso.sh
#: bad interpreter: No such file or directory

and

$ sh -x img2iso.sh
$

What is more strange:
$ cat img2iso.sh
done$ exists! Incrementing suffix"

I have triple checked that the directory does exist and is spelled correctly with proper case.

In the second case nothing happens but a prompt change. No echoes.

In the img2iso directory no files have changed extension after running the script.

The concatenate I can't even begin to understand. It seems very odd to prompt the last echo like that.

I will have to look this over carefully again and again as I'm sure your code is good. I just can't see what I'm missing on my side.

I'm on a MacOS X 10.4, perhaps this matters? I use Smultron as editor.

how bout this:

for file in $(find . -type f -iname '*.img'); do
  mv $file ${file/img/iso}
done

This doesnt take filenames nor directories with whitespaces in them, to adapt the above to that, do:

save_ifs=$IFS ; IFS='
'
for file in $(find . -type f -iname '*.img'); do
  mv "$file" "${file/img/iso}"
done
IFS=$save_ifs

hope this helps
cheers

EDIT: This works for bash, but if I remember correctly the default shell on macosX is bash...

Now it's clear why the script doesn't work :slight_smile:

Unfortunately I really don't know anything about the Mac's world, so I can't help you anymore.

The obvious thing about the message "bad interpreter" is that it can't find the bash binary "/bin/bash" defined at the top of the script. If you issue "ls -l /bin/bash" what's the output?

About the "sh -x" thing, on Linux "sh" is a symbolic link to bash and it does work. On Mac I dont'know. To overcome this you can insert a line with the command "set -x" just before the video directory variable assignment. The effect is the same, but before you have to fix the interpreter problem or this is totally useless.

And about the "cat" command, it seems that your script file is a bit messed up.....

Perhaps a dos2unix or something similiar in Mac.

For your original script

#!/bin/bash

# Set the video directory here
VIDEO_ROOT_DIRECTORY="/Users/astrid/NFS/scripts/img2iso/";

# Check if the directory exist or not
if [ -d "$VIDEO_ROOT_DIRECTORY" ]; then
  cd $VIDEO_ROOT_DIRECTORY
else
  print "ERROR: Unable to reach directory - or it does not exist!";
  exit 1
fi

for imgfile in $(find . -type f -iname "*.img")
do
  if [ ! -f ${imgfile%.img}.iso ] ; then
    mv ${imgfile} "${imgfile%.img}.iso"
    print "[${imgfile} -> ${imgfile%.img}.iso]"
  else
    mv ${imgfile} "${imgfile%.img}-1.iso"
    print "[${imgfile} -> ${imgfile%.img}-1.iso]"
done

exit 0

Not tested tho'.

Considering the initial requirement (recursively mv .img to .iso),
with zsh:

cd /Users/astrid/NFS/scripts/img2iso/
autoload -U zmv # put it in your .zshrc
zmv -n '(**/)(*).img' '$1$2.iso'

If the result is correct
remove the n flag:

zmv '(**/)(*).img' '$1$2.iso'

Otherwise:

find /Users/astrid/NFS/scripts/img2iso -name '*.img' -exec sh -c 'f="${1%.img}.iso"
[ ! -f "$f" ]&&mv "$1" "$f"' - {} \;

With all this help I know I will get it going!
Thank you so much for your attention, it gives a lot of inspiration. I havn't come around to finish the script yet (it's that other life with kids, laundry, office work etc.) but I'll check back when I'm finished, real soon I hope.

By the way, bash seems to be living here:

$ ls -l /bin/bash
-rwxr-xr-x   1 root  wheel  1068844 Dec 12  2006 /bin/bash

(and the same goes for zsh, nice!)

A bit optimized (without the useless sed), parametric and verbose version:

test ~ $ cat img2iso.sh
#!/bin/bash

#VIDEO_ROOT_DIRECTORY="/Users/astrid/NFS/scripts/img2iso"
VIDEO_ROOT_DIRECTORY="/home/test/video"

IN_EXT=".img"
OUT_EXT=".iso"

for infile in $(find "$VIDEO_ROOT_DIRECTORY" -name "*${IN_EXT}" -type f)
do
   echo "----------"
   echo "Processing INFILE <$infile>"
   n=0
   exit=""
   suffix=""

   while [ ! "$exit" ]
   do
      newname="${infile%${IN_EXT}}${suffix}${OUT_EXT}"
      if [ ! -f "$newname" ]
      then
         echo "NEW NAME OK! Renaming to <$newname>"
         mv "$infile" "$newname"
         exit="y"
      else
         echo "NEW NAME <$newname> already exists! Incrementing suffix"
         n=$((n+1))
         suffix="-$n"
      fi
   done
done

And the output before and after execution:

test ~ $ ls -lR /home/test/video
/home/test/video:
total 16
-rw-r--r-- 1 test test    0 Feb 17 12:00 aaa.img
-rw-r--r-- 1 test test    0 Feb 17 12:00 bbb.img
-rw-r--r-- 1 test test    0 Feb 17 12:00 bbb.iso
-rw-r--r-- 1 test test    0 Feb 17 12:00 ccc-1.iso
-rw-r--r-- 1 test test    0 Feb 17 12:00 ccc.img
-rw-r--r-- 1 test test    0 Feb 17 12:00 ccc.iso
-rw-r--r-- 1 test test    0 Feb 17 12:00 ddd-1.iso
-rw-r--r-- 1 test test    0 Feb 17 12:00 ddd.img
-rw-r--r-- 1 test test    0 Feb 17 12:00 eee.img
drwxr-xr-x 2 test test 4096 Feb 17 12:06 sub1
drwxr-xr-x 2 test test 4096 Feb 17 12:06 sub2

/home/test/video/sub1:
total 4
-rw-r--r-- 1 test test  0 Feb 17 12:06 fff.img
-rw-r--r-- 1 test test  0 Feb 17 12:06 fff.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 ggg-1.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 ggg-2.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 ggg.img
-rw-r--r-- 1 test test  0 Feb 17 12:06 ggg.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 hhh-1.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 hhh.img

/home/test/video/sub2:
total 4
-rw-r--r-- 1 test test  0 Feb 17 12:06 iii.img
-rw-r--r-- 1 test test  0 Feb 17 12:06 lll.img
-rw-r--r-- 1 test test  0 Feb 17 12:06 mmm.img



test ~ $ ./img2iso.sh
----------
Processing INFILE </home/test/video/ccc.img>
NEW NAME </home/test/video/ccc.iso> already exists! Incrementing suffix
NEW NAME </home/test/video/ccc-1.iso> already exists! Incrementing suffix
NEW NAME OK! Renaming to </home/test/video/ccc-2.iso>
----------
Processing INFILE </home/test/video/aaa.img>
NEW NAME OK! Renaming to </home/test/video/aaa.iso>
----------
Processing INFILE </home/test/video/sub1/ggg.img>
NEW NAME </home/test/video/sub1/ggg.iso> already exists! Incrementing suffix
NEW NAME </home/test/video/sub1/ggg-1.iso> already exists! Incrementing suffix
NEW NAME </home/test/video/sub1/ggg-2.iso> already exists! Incrementing suffix
NEW NAME OK! Renaming to </home/test/video/sub1/ggg-3.iso>
----------
Processing INFILE </home/test/video/sub1/fff.img>
NEW NAME </home/test/video/sub1/fff.iso> already exists! Incrementing suffix
NEW NAME OK! Renaming to </home/test/video/sub1/fff-1.iso>
----------
Processing INFILE </home/test/video/sub1/hhh.img>
NEW NAME OK! Renaming to </home/test/video/sub1/hhh.iso>
----------
Processing INFILE </home/test/video/eee.img>
NEW NAME OK! Renaming to </home/test/video/eee.iso>
----------
Processing INFILE </home/test/video/sub2/mmm.img>
NEW NAME OK! Renaming to </home/test/video/sub2/mmm.iso>
----------
Processing INFILE </home/test/video/sub2/iii.img>
NEW NAME OK! Renaming to </home/test/video/sub2/iii.iso>
----------
Processing INFILE </home/test/video/sub2/lll.img>
NEW NAME OK! Renaming to </home/test/video/sub2/lll.iso>
----------
Processing INFILE </home/test/video/bbb.img>
NEW NAME </home/test/video/bbb.iso> already exists! Incrementing suffix
NEW NAME OK! Renaming to </home/test/video/bbb-1.iso>
----------
Processing INFILE </home/test/video/ddd.img>
NEW NAME OK! Renaming to </home/test/video/ddd.iso>



test ~ $ ls -lR /home/test/video
/home/test/video:
total 16
-rw-r--r-- 1 test test    0 Feb 17 12:00 aaa.iso
-rw-r--r-- 1 test test    0 Feb 17 12:00 bbb-1.iso
-rw-r--r-- 1 test test    0 Feb 17 12:00 bbb.iso
-rw-r--r-- 1 test test    0 Feb 17 12:00 ccc-1.iso
-rw-r--r-- 1 test test    0 Feb 17 12:00 ccc-2.iso
-rw-r--r-- 1 test test    0 Feb 17 12:00 ccc.iso
-rw-r--r-- 1 test test    0 Feb 17 12:00 ddd-1.iso
-rw-r--r-- 1 test test    0 Feb 17 12:00 ddd.iso
-rw-r--r-- 1 test test    0 Feb 17 12:00 eee.iso
drwxr-xr-x 2 test test 4096 Feb 17 12:09 sub1
drwxr-xr-x 2 test test 4096 Feb 17 12:09 sub2

/home/test/video/sub1:
total 4
-rw-r--r-- 1 test test  0 Feb 17 12:06 fff-1.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 fff.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 ggg-1.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 ggg-2.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 ggg-3.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 ggg.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 hhh-1.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 hhh.iso

/home/test/video/sub2:
total 4
-rw-r--r-- 1 test test  0 Feb 17 12:06 iii.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 lll.iso
-rw-r--r-- 1 test test  0 Feb 17 12:06 mmm.iso