Hello you wonderful people, I have a little problem creating a Bash Script. I have 7000 image files (dicoms). These files belong together and should be in order in ONE directory. However, the program that is creating these files appears to open a new subfolder every 2048 files and starts over with new. I would like to change the images' names in these subfolders.

So lets say I have one folder with 2048 images (named IM_0001 to IM_2048). I have one subsequent folder with 900 images. (named, again IM_0001 to IM_0900).

I would like to:

  1. For loop through all files in the second folder.
  2. mv IM_{number} IM_{number+2048} (so IM_0001 becomes IM_2049 and so on)

That is, basically all. Is there a simple, efficient way to do this (or something similar)? I am, unfortunately, not very familiar with the Bash syntax, so any input would be greatly appreciated. The Names should be similar! So simply renaming all items in the second folder into (for example) JM_0001 to JM_0900 will cause my import program (I need to use that particular tool, unfortunately) to screw up.

Thank you!


3 Answers 3


If there is no extention in files name:

for i in secondfolder/IM_* ; do mv "$i" "${i%_[0-9]*}_$[10#${i##*_}+2048]" ; done
  • This answer was the most helpful as it includes a way to prevent the octal-system caused "value too great for base"-error.
    – Stefan
    Commented Mar 2, 2015 at 15:16

Simple way in bash:

for i in $(ls /path/to/your-directory); do
name=$(echo "$i" | cut -d '_' -f1)
num=$(echo "$i" | cut -d'_' -f2)
num1=$(( num + 2048 ))
mv "$i" "${name}_$num1"

Here a basic way to do something like this using a shell script and awk.

This example script is fairly explicit for your particular case, its using the the second field in the file-name is a valid integer. And trusts that there no stray underscores in the file-names. A more general purpose script would validate that field 2 is just numbers and make the field separator a parameter. Also it assumes that there no file extension (like .img or .png)

WORKDIR=/(Directory where the files to be renamed are)
echo "Old File    New File"
ls IM_* | while read i
   newfile=`echo $i | awk -F_ -v incby=$NUM2ADD '{t=$2 + incby;printf "IM_%s",t;}'`
   echo   $i    $newfile
   # after a dry run to test, replace 'echo' with 'mv' onces your sure of the result. 

Since having a file extension is fairly likely, you can change the awk line to:

newfile=`echo $i | awk -F[_.] -v incby=$NUM2ADD '{t=$2 + incby; printf "IM_%s.%s",t,$3;}'` 

This preserves the file extension and uses both underscore _ and period as field separators.

You must log in to answer this question.

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