Rename directories, subdirectories, files recursively that contain matching string

Problem:

I have copied /u01 directory (containing Oracle software) from another node. The Oracle software home includes directories and files with hostnames.

My task was to rename all directories, subdirectories, and files containing the specific hostname (in my case rac2) into rac1.

Let me show you the folder hierarchy that is challenging when you want to rename by script. For simplicity, this hierarchy is made up, but this type of dependency exists in /u01:

/u01/first_level_rac2/second_level_rac2/third_level_rac2.txt

We want to have:

/u01/first_level_rac1/second_level_rac1/third_level_rac1.txt

So finally, all folders or files containing the string rac2 should be replaced with rac1.

The challenge here is that you need to start renaming from the third_level, then rename second_level and later first_level. Otherwise, you will have accessibility issues with other subdirectories or files.

Solution:

If you want a shortcut, here is the code:

[root@rac1 ~]# find /u01 -depth -name "*rac2*" | while read i ; do
newname="$(echo ${i} |sed 's/\(.*\)rac2/\1rac1/')" ;
echo "mv" "${i}" "${newname}" >> rename_rac2_rac1.sh;
done

Later you need to run rename_rac2_rac1.sh file, which will contain mv statements for each matching file or folder.

Let me explain,

find /u01 -depth -name "*rac2*" – This will find all files and folders that contain rac2 keyword and will display the output with depth-first order.

Without depth, the output is the following:

/u01/first_level_rac2
/u01/first_level_rac2/second_level_rac2
/u01/first_level_rac2/second_level_rac2/third_level_rac2.txt

With -depth, you will see the next order:

/u01/first_level_rac2/second_level_rac2/third_level_rac2.txt
/u01/first_level_rac2/second_level_rac2
/u01/first_level_rac2

"$(echo ${i} |sed 's/\(.*\)rac2/\1rac1/')" – In this line, the value of i iterator (each line from find command) will be redirected to sed command that will replace the first occurrence of rac2 keyword searching from backward.

Later old name and a new name will be concatenated with mv statement and saved into rename_rac2_rac1.sh

This will be mv statements generated by the script:

mv /u01/first_level_rac2/second_level_rac2/third_level_rac2.txt /u01/first_level_rac2/second_level_rac2/third_level_rac1.txt

mv /u01/first_level_rac2/second_level_rac2 /u01/first_level_rac2/second_level_rac1

mv /u01/first_level_rac2 /u01/first_level_rac1

How to display certain line from a text file in Linux?

Sometimes script fails and error mentiones the line number, where there is a mistake. One option is to open a file and go to the mentioned line.

I am going to show you how to use SED to print only the certain line from the script file:

# sed -n ’80p’ /u01/app/18.3.0/grid/crs/script/mount-dbfs.sh

“My 80th line”

Where 80 is the line number and p “print[s] the current pattern space”