Go Back   HowtoForge Forums | HowtoForge - Linux Howtos and Tutorials > Linux Forums > Programming/Scripts

Do you like HowtoForge? Please consider supporting us by becoming a subscriber.
Thread Tools Display Modes
Old 25th May 2011, 20:23
sahil_jammu sahil_jammu is offline
Junior Member
Join Date: May 2011
Location: Bangalore
Posts: 2
Thanks: 0
Thanked 1 Time in 1 Post
Default Traverse file structure from top and rename the immediate parent

Hello All,

I am trying to write a script to:-

1. Traverse entire file system, look for directories which has .git directory in it
2. Rename the immediate parent directory to <orignal_name.git>
3. Traverse new file structure and look for all directories with <original_name>.git
4. cd to that directory and remove its contents
5. once everything inside the directory is deleted, create a file

Step 1:- find * -type d -iname '.git'
Step 2:-
function rename_git_parent
for file in "$1"/*
cd .. | $(pwd) -exec mv '{}' '{}'.dir ';'
return 1

//i am not too sure if its the right way of doing it, or shall i use dirname..

How shall i go about step2 and ownwards...
Reply With Quote
Sponsored Links
Old 27th May 2011, 23:16
sahil_jammu sahil_jammu is offline
Junior Member
Join Date: May 2011
Location: Bangalore
Posts: 2
Thanks: 0
Thanked 1 Time in 1 Post

Got the solution:-
This will find all directories named .git, and make sure their parent directories have names ending with .git:
find / -depth -type d -name .git -printf '%h\0' | while read -d "" old ; do
[ ! -d "$old" ] && continue
[ "$old" == "$new" ] && continue

if [ -e "$new" ]; then
echo "$new: Already exists" >&2
mv -vi "$old" "$new"
The -depth flag will tell find to descend first, so that all child directories are checked before a parent directory. The -printf '%h\0' option will output the parent directory name and a NUL separator (zero byte; the only thing you cannot have in pathnames). If using Bash, the -d "" option to the read builtin will read such NUL-separated pathnames; other shells won't support that.

(If you are not using Bash, use -printf "%h\n" | while read dir ; do instead. It'll bork if you have directories with a newline in their names, though.)

The first continue test checks if this directory has already been renamed something else. (I think it is impossible for that to happen, but it doesn't hurt to check.)
The second continue test checks if the directory already has an acceptable name.

If the new directory name is still available, the directory is renamed.

This will find empty all directories that have names ending in .git (but not just .git), and create file "file" in it:
find / -depth -type d -name '?*.git' -printf '%p\0' | while read -d "" dir ; do
find "$dir/" -depth -mindepth 1 -delete
touch "$dir/file"
The glob pattern ?*.git matches (anything not empty).git .

The inner find deletes everything in the directory, but not the directory itself (since minimum depth is 1). Although rm usually feels like the choice for this, it'd either delete the directory itself too, skip any files or subdirectories having a dot in the name, or throw an error about nonexistent files, depending on what you supply to it. If you delete and then recreate the directory, you'll lose any extended attributes. So, surprisingly, find is better for this.
Reply With Quote
The Following User Says Thank You to sahil_jammu For This Useful Post:
falko (28th May 2011)


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

All times are GMT +2. The time now is 14:57.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.