LinuxQuestions.org
View the Most Wanted LQ Wiki articles.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices

Reply
 
Search this Thread
Old 05-25-2011, 04:56 AM   #1
sahil.jammu
Member
 
Registered: Jun 2008
Distribution: Ubuntu
Posts: 83

Rep: Reputation: 15
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


Code:-
Step 1:- find * -type d -iname '.git'
Step 2:-
function rename_git_parent
{
for file in "$1"/*
do
cd .. | $(pwd) -exec mv '{}' '{}'.dir ';'
done
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...
 
Old 05-26-2011, 12:41 AM   #2
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

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

    if [ -e "$new" ]; then
        echo "$new: Already exists" >&2
    else
        mv -vi "$old" "$new"
    fi
done
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:
Code:
find / -depth -type d -name '?*.git' -printf '%p\0' | while read -d "" dir ; do
    find "$dir/" -depth -mindepth 1 -delete
    touch "$dir/file"
done
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.

However, I'm utterly at loss at why you would like to do something like this, and if this actually is what you want to do. I'm afraid you may delete much more than you originally intended..
 
1 members found this post helpful.
Old 05-27-2011, 03:32 PM   #3
sahil.jammu
Member
 
Registered: Jun 2008
Distribution: Ubuntu
Posts: 83

Original Poster
Rep: Reputation: 15
Thanks Nominal Animal,

Your inputs were quite useful and some of the things were new to me and it was good learning experience.

-----
However, I'm utterly at loss at why you would like to do something like this, and if this actually is what you want to do. I'm afraid you may delete much more than you originally intended..
-----

//I'll share the reason for this, i have recently started working on android open source projects, was playing around with the entire file structure of Android and i was curious to see the projects which are getting tracked by git, so .git find helped me to achieve that, renaming and content deletion ensured there is nothing inside those directories now, and after that i can execute commands like git init to set this up...

Your pointers were quite useful.

Thanks...
 
Old 05-27-2011, 03:53 PM   #4
sahil.jammu
Member
 
Registered: Jun 2008
Distribution: Ubuntu
Posts: 83

Original Poster
Rep: Reputation: 15
Just a quick doubt here:-

Now i would like to perform 1 more operation here:-

1. Traverse entire file structure and search for all the directories which has .git directory present in it...

2. In successful cases, go inside those directories and perform one operation:-
x = /home/myproject/mystuff/testing (some common path which will be used in all cases)
Objective:- <some command> $x/immediate_dir_name.git


I am expecting there will be 80-90 successful scenarios where the .git directory will be present inside the parent, now within each of those directories, i would like to perform some command on a common path ($x) followed by original_name_of_the_parent appended by .git


For ex:-
if there is a dir with name testing having .git, i would like to execute command inside testing directory
<some command> $x/testing.git


Will this work?? Is this the right way of doing it...
----------
x = /home/myproject/mystuff/testing
find $PWD -name '.git' -type d | while read -d "" dir ; do
<some command> "$dir/ $x/$dir.git"
---------
 
Old 05-27-2011, 06:33 PM   #5
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942
Quote:
Originally Posted by sahil.jammu View Post
if there is a dir with name testing having .git, i would like to execute command inside testing directory
<some command> $x/testing.git

Will this work?? Is this the right way of doing it...
----------
x = /home/myproject/mystuff/testing
find $PWD -name '.git' -type d | while read -d "" dir ; do
<some command> "$dir/ $x/$dir.git"
---------
No, the parameter to some command is garbled. Try this:
Code:
prefix=/home/myproject/mystuff/testing
find . -depth -type d -name .git -printf '%h\0' | while read -d "" path ; do (
    cd "$path" || exit $?
    name="`basename "$path"`"
    echo command "$prefix/$name.git"
) done
Because the loop body is in parentheses, each $path starts from fresh (a new subshell). If you omit the parentheses, the cd's will be cumulative. If you want the commands to be run in parallel, change the last line to
Code:
) & done ; wait
Since the while loop itself is right side of a pipe |, the working directory is not affected at all outside the loop.

The cd "$path" || exit $? command will change the working directory within the loop body to the directory containing the .git subdirectory. If it fails, the current subshell exits. (Since the loop body is in parentheses, only that directory is skipped. If there were no parentheses, cd "$path" || continue would have the same effect, but then the cd's would be cumulative.)

The basename line will save the directory name in $name.
Thus, $name is the name and $path the full path to the directory that contains a .git directory. (The full path to the .git directory is of course"$path/.git".)

The echo outputs the command. That way it the snippet won't do any changes to anything, but you'll see the commands that would have been run. If they look OK, drop the echo and rerun the snippet, to execute the commands.
 
1 members found this post helpful.
Old 05-30-2011, 07:57 AM   #6
sahil.jammu
Member
 
Registered: Jun 2008
Distribution: Ubuntu
Posts: 83

Original Poster
Rep: Reputation: 15
Thanks a lot.
Your inputs were very useful.


Regards
Sahil
 
Old 05-31-2011, 02:04 AM   #7
sahil.jammu
Member
 
Registered: Jun 2008
Distribution: Ubuntu
Posts: 83

Original Poster
Rep: Reputation: 15
Hello,
Just a quick query:-
---------------------
Current script:-

################################################################################################
prefix=user@my-server:
find . -depth -type d -name .git -printf '%h\0' | while read -d "" path ; do (
cd "$path" || exit $?
name="`basename "$path"`"
echo <command> "$prefix$PWD.git"
) done
#################################################################################################
Output:-
<command> user@my-server:/home/git/mirror/android/adb/OpenWnn.git
<command> user@my-server:/home/git/mirror/android/adb/cts.git
<command> user@my-server:/home/git/mirror/android/adb/dalvik.git
<command> user@my-server:/home/git/mirror/android/adb/ndk.git
#################################################################################################

Desired output:-

<command> user@my-server:/android/adb/OpenWnn.git
<command> user@my-server:/mirror/android/adb/cts.git
<command> user@my-server:/android/adb/dalvik.git
<command> user@my-server:/mirror/android/adb/ndk.git

##################################################################################################


How shall i go about changing the absolute path to relative path, so that /home/git/mirror/android/adb/ndk.git
gets converted to /mirror/android/adb/ndk.git

//echo <command> "$prefix$PWD.git" ?? - anything for relative path??

##################################################################################################
 
Old 05-31-2011, 02:09 AM   #8
EricTRA
Guru
 
Registered: May 2009
Location: Gibraltar, Gibraltar
Distribution: Fedora 18 with Awesome WM
Posts: 6,805
Blog Entries: 1

Rep: Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290Reputation: 1290
Hello,

Please don't double post your question. It'll only confuse both you and us on where the conversation is taking place. You opened a new thread with the same question. Reporting the other one as duplicate.

Kind regards,

Eric

Last edited by EricTRA; 05-31-2011 at 02:12 AM.
 
  


Reply

Tags
exec, filesystem, find, move, rename


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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


Similar Threads
Thread Thread Starter Forum Replies Last Post
Traverse the file system and Rename (xargs or sed?) sahil.jammu Linux - General 19 05-25-2011 10:15 AM
Rename file to parent directory name ExWizzard Linux - Newbie 2 12-11-2009 04:19 PM
Directory Traverse & Rename Script fsckin Programming 3 10-05-2008 01:43 AM
bash: make rename script traverse directories morrolan Programming 2 11-08-2006 10:52 AM
is there a way to traverse a directory structure & execute a command hemlock Linux - Newbie 1 09-07-2002 12:22 AM


All times are GMT -5. The time now is 01:09 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration