I have a main directory that has four folders f1, f2, f3 and f4 each of these folders has 10 folders, and each of these 10 folders ff1...ff10 has some .jpeg images with some names lets say image1.... and so on. What I want to know is how to rename these .jpeg images in each of these folders of the 10 folders in each of f1, f2, f3 and f4, so that I will concatenate the parent folders in the beginning of its name, for example of image1.jpeg is located in f3/ff1 then its name will be f3_ff1_image1.jpeg, same with all the other images in the other 10 folders in each of the four main folders. If anyone can please advise how this can be done in a .sh file.


Create a simple file changeName.sh as follow:

    fileName=$(basename $1)
    filepath=$(dirname $1)
    secondDir=$(basename $filepath)
    firstDir=$(basename $(dirname $filepath))
    parentDir=$(basename $(dirname $(dirname $filepath)))
    mv $1 $filepath/${parentDir}_${firstDir}_${secondDir}_$fileName

save it, for example in /home/yourUser/bin.

Change permission to changeName.sh:

chmod +x /home/yourUser/bin/changeName.sh

Open you /home/yourUser/.bashrc file and add at the end this line:


save it and reload it:

source .bashrc

Now you have a new utility that can change name to file using folder as part of name.

Try this:

find mainDirectory -name "*.jpeg" -exec changeName.sh {} \;

mainDirectory can be absolute or relative.

Tested on lubuntu 12.04

dirname strip last component from file name while basename strip directory and suffix from filenames.

So to get third level of directory:

   parentDir=$(basename $(dirname $(dirname $filepath)))
| improve this answer | |
  • could you tell me, what if I want to rename using one higher level? so that I will include the parent folder of f1,f2,f3 or f4, so that the name will include one more higher folder level name? – Tak Sep 28 '14 at 18:50
  • 1
    Updated answer. – Lety Sep 28 '14 at 18:52
  • and where I'm going to put this in changeName.sh? , sorry for asking but I'm a beginner. – Tak Sep 28 '14 at 18:54
  • 1
    Sorry, I updated answer. – Lety Sep 28 '14 at 18:57

With a loop and some bash string manipulations

while read -rd $'\0' f; do 
  d="${f%/*}"; p="${d/\//_}";
  echo mv -- "$f" "${d}/${p}_${f##*/}"
done < <(find -type f -name '*.jpeg' -printf '%P\0')

(remove the echo once you've confirmed it matches the files correctly)

With the perl-based rename command and bash globstar

shopt -s globstar
rename -nv -- 's|(f\d+)/(ff\d+)/(image\d+)|$1/$2/$1_$2_$3|' **/*.jpeg

(remove the -nv once you've confirmed it matches the files correctly)

| improve this answer | |

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.