LinuxQuestions.org
Latest LQ Deal: Complete CCNA, CCNP & Red Hat Certification Training Bundle
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 03-10-2012, 07:43 PM   #1
sysmicuser
Member
 
Registered: Mar 2010
Posts: 332

Rep: Reputation: 0
how to get directories dynamically in a script


Folks,

I need some assistance with regards to getting a sub-directory names dynamically.

Say for example I am i directory called test
so,pwd gives answer as "test"
In directory, we have 5 subdirectories called test01, test-2..test05.

test01-05 directories has further n no of subdirectories each which we should not care as we intend to run a Perforce command in these subdirectories.

what I want is a technique to gather all subdirectoires name but not name of directories in current working directory that is NOT" test01,test02,test03,test04,test05.

I did something like this.

find . -type d -not -ls |awk '{print $9}' -not -name "delete_me_later*"

But this is not bloody working

ANy clues or pointers?
 
Old 03-10-2012, 07:57 PM   #2
Cedrik
Senior Member
 
Registered: Jul 2004
Distribution: Slackware
Posts: 2,140

Rep: Reputation: 242Reputation: 242Reputation: 242
I miss something in the logic, you are in "test" current directory, want to perform a command in subdirectories of test01-05 directories that are in current directory, you still need to know the parent directory (test01-05) in order to access their subdirectories, no ?
 
Old 03-10-2012, 08:02 PM   #3
sysmicuser
Member
 
Registered: Mar 2010
Posts: 332

Original Poster
Rep: Reputation: 0
yes, but I want to print only subdirectories name not the name of their parent directories which is test01-05, I jope I have claried it further.
 
Old 03-10-2012, 08:08 PM   #4
Cedrik
Senior Member
 
Registered: Jul 2004
Distribution: Slackware
Posts: 2,140

Rep: Reputation: 242Reputation: 242Reputation: 242
Would this work:
Code:
cd /path/to/test
for subdir in ./*/*/; do
  echo $(basename $subdir)
done

Last edited by Cedrik; 03-10-2012 at 08:12 PM.
 
1 members found this post helpful.
Old 03-10-2012, 08:27 PM   #5
linuxxer
Member
 
Registered: Apr 2011
Location: I have my own planet
Distribution: SlackwareŽ
Posts: 82
Blog Entries: 1

Rep: Reputation: Disabled
Quote:
Originally Posted by sysmicuser View Post
Folks,

I need some assistance with regards to getting a sub-directory names dynamically.

Say for example I am i directory called test
so,pwd gives answer as "test"
In directory, we have 5 subdirectories called test01, test-2..test05.

test01-05 directories has further n no of subdirectories each which we should not care as we intend to run a Perforce command in these subdirectories.

what I want is a technique to gather all subdirectoires name but not name of directories in current working directory that is NOT" test01,test02,test03,test04,test05.

I did something like this.

find . -type d -not -ls |awk '{print $9}' -not -name "delete_me_later*"

But this is not bloody working

ANy clues or pointers?

Hi sysmicuser,

Try this,
Code:
find . -mindepth 2 -type d -print
 
1 members found this post helpful.
Old 03-10-2012, 08:51 PM   #6
sysmicuser
Member
 
Registered: Mar 2010
Posts: 332

Original Poster
Rep: Reputation: 0
sorry Guys it is still not working!

@Cedrick
The logic which you gave performed the operation for only two directories in curent working directory, rest other 3 directories were untouched by script. so out of 9 directories at a level it performed that operation only on two and not on 7.

@linuxxer
I did thought of your solution before I posted my query on forum.
The problem there is it doesn't goes on 3 rd level subdirectories and perform the operation I want..

So it seems my communication is not good enough to reach the audience.

Let me put in simple and straight foward way.

We need to traverse from Level 1 directoy to it's all sub-directoies and perform a simple p4 diff -f * operation.

Please note that it is important that we are oblivious of how many sub-directories are there down the line.

Script must have intelligence to determine all subdirectories, there is one catch, we need to tell the script that don't look at any directory or sub-directories who names start or are like "delete_me_later"

I hope I have communicated my requirement in most simplest way.

Thanks
 
Old 03-10-2012, 09:32 PM   #7
devUnix
Member
 
Registered: Oct 2010
Location: Bengaluru, India
Distribution: RHEL 5.1 on My PC, & SunOS / Sun Solaris, RHEL, SuSe, Debian, FreeBSD and other Linux flavors @ Work
Posts: 576

Rep: Reputation: 48
Use this command:

Code:
ls -lFR | grep -F ./ | cut -d '/' -f3-100 | grep -v ^$
You will not see the directories found in the current directory:
To exclude those names that start with "do_not_delete" simply add this: " | grep -v do_not_delete" and those names will be excluded:



Code:
ls -lFR | grep -F ./ | cut -d '/' -f3-100 | grep -v ^$ | grep -v do_not_delete
Example:

"Awk" and "Bash", for example, directories are in "bin" directory which is in the home directory from where I am running this command:

Code:
[demo@localhost ~]$ ls -lFR | grep -F ./ | cut -d '/' -f3-100 | grep -v ^$
Awk:
AWK:
Bash:
Bash/java_1:
Bash/java_2:
Bash/java_3:
Bash/java_4:
Bash/logs:
Bash/try:
C:
Code:
"bin" is not listed above but its sub-directories are listed above:

[demo@localhost ~]$ ls -ltrF bin | grep /$
drwxrwxr-x. 2 demo demo  1024 Oct 30 17:50 Awk/
drwxrwxr-x. 8 demo demo  1024 Jan 31 20:34 Bash/
...
It will go into any deep level. Just it will not display the directory names you do not wish to as specified by your comments and posts.
 
1 members found this post helpful.
Old 03-10-2012, 11:21 PM   #8
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,576
Blog Entries: 31

Rep: Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195Reputation: 1195
Is this what you want?

Setting up ...
Code:
c@CW8:~$ cd /tmp
c@CW8:/tmp$ mkdir -p tmp/a/b/c/d
c@CW8:/tmp$ mkdir -p tmp/b/c/d/e
c@CW8:/tmp$ mkdir -p tmp/c/d/e/f
c@CW8:/tmp$ mkdir -p tmp/d/e/f/g
Now the command ...
Code:
c@CW8:/tmp$ cd tmp
c@CW8:/tmp/tmp$ find */* -type d
a/b
a/b/c
a/b/c/d
b/c
b/c/d
b/c/d/e
c/d
c/d/e
c/d/e/f
d/e
d/e/f
d/e/f/g
 
1 members found this post helpful.
Old 03-11-2012, 12:42 AM   #9
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,243

Rep: Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684
I think instead of trying to verbally explain the issue, which is losing some of us, that you do as catkin has done and show an example of what the structure is like that you have and
then an example of what the output would be based on the previous example.
 
1 members found this post helpful.
Old 03-11-2012, 01:25 AM   #10
sysmicuser
Member
 
Registered: Mar 2010
Posts: 332

Original Poster
Rep: Reputation: 0
Thank you all for all your assistance, your support is highly appreciated.

As grail suggested and as catkin has done, here comes a better picture of what I am trying or want to do.

Code:
[user01@centos-flash test]$ls -R|find -type d|grep -v "do_not_delete*"
.
./t1
./t2
./t2/s1
./t2/b1
./t2/b1/b11
./t2/b1/b12
./t3
./t4
./t5
./t6
./t7/x1
./t7/x1/x11
./t7/x1/x12
./t8
./t9
./t9/z1
./t9/z2
[user01@centos-flash test]$pwd
/x/y/z/test

[user01@centos-flash test]$ls -R|find -type d
.
./t1
./t2
./t2/s1
./t2/b1
./t2/b1/b11
./t2/b1/b12
./t3
./t4
./t5
./t6
./t7/x1
./t7/x1/x11
./t7/x1/x12
./t8
./t9
./t9/z1
./t9/z2
./do_not_delete
./do_not_delete_later
Note that test in my current working directory and all directories beneath it are shown here, I have changed names to keep security freaks happy.

What I want is, I should go to directory t1, run command p4 diff -f * as that is the only directory and there are no more directories underneath it.
Once I am done then come back to test directory or go to directory t2, now t2 is interesting directory,

Let us have a look at its structure,
Code:
./t2
./t2/s1
./t2/b1
./t2/b1/b11
./t2/b1/b12
it has two directories underneath it and 1 sub-directory(b1) has again two sub-directories.
So I ideally I want something like go to t2/b1/b12 run p4 diff -f * command, then go to t2/b1/b11 run p4 diff -f * command
once I have covered both b11 and b12 directories I should not run p4 diff -f * command in /t2/b1 directory as the output is misleading.

Come back to t2/s1 again run command p4 diff -f *, come back to t2 directory, now when I run p4 diff -f * command in t2 directory it should eliminate all sub-directory(ies) and this procedure is repeated so on and so forth until t9..


Earlier I was doing "hard coding"

so my for loop was
Code:
for i in "t1 t2 t3 .."
do
p4 diff -f *
done
then I thought its not good idea as we start doing expansion under those directories we would be losing lots of information and reporting won't be a rock solid solution.

so I thought lets us something called as parametrized directory names and this idea was born...

so it would something like this
Code:
for i in $(ls -R|find -type d)
but there are complications in running p4 diff command as perforce doesn't recognize directory but a file.

This is what I want to do.

Not sure if its complex or easy to implement.
 
Old 03-11-2012, 04:39 AM   #11
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,243

Rep: Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684
So maybe something like:
Code:
#!/bin/bash

while read -r path
do
    [[ $last == $path ]] || echo $path
    last=${path%/*}
done< <(find -depth -path './do_not*' -prune -o -print)
Change echo for what you need to do
 
1 members found this post helpful.
Old 03-11-2012, 07:51 AM   #12
sysmicuser
Member
 
Registered: Mar 2010
Posts: 332

Original Poster
Rep: Reputation: 0
@grail

Thanks for that grail, getting closely there and it feels the trails and tribulation gives much pleasure and satisfaction in learning anything

Few question though if you don't mind.

I am not sure why do_not_delete and do_not_delete_later are not getting ommited?

Also,
I want to understand the logic behind your script.
Code:
while read -r path
do
    [[ $last == $path ]] || echo $path
    last=${path%/*}
done< <(find -depth -path './do_not*' -prune -o -print)
Oaky, here we are reading a variable called "path", then we start the loop as we read variable path
there is OR switch between [[ $last == $path ]] || , meaning atleast one of them are going to get executed?
echo $path not sure what is done here and again in next statement last=${path%/*}
then we end loop by saying done and there is < and a "space" and again < it doesn't look like a here document.....

Interesting part is find command
In find command as I understand, we say process content of directories before the directory itself.
could not get -path './do_not*' -prune -o -print although manual of find does refer to some example...


Please help me understand, Thank you.
 
Old 03-11-2012, 08:28 AM   #13
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,243

Rep: Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684
Quote:
I am not sure why do_not_delete and do_not_delete_later are not getting ommited?
So just to confirm, if you run the following at the command line:
Code:
find -depth -path './do_not*' -prune -o -print
This shows you all directories including do_not_delete and do_not_delete_later? It does not show those for me.
I would however add -type d (which I forgot)
Quote:
here we are reading a variable called "path"
No. We are reading the output of the find into the variable "path", so although at the end the find is feeding our loop and yes < <() does have a space between the two < signs.
This process substitution.
Quote:
there is OR switch between [[ $last == $path ]] || , meaning atleast one of them are going to get executed?
Again no, or at least not exactly. What is between [[ and ]] is tested and if false what is on the other side of || is executed. Currently it is a simple echo but you could change this to be
the task you wish to perform on each directory.
Code:
last=${path%/*}
Assign to the variable last, everything that is in variable path except everything from the last / onwards, so if path equals ./t2/b1/b11 then last will equal ./t2/b1, hence if we have been
inside a later directory we do not need to process one directory up.
Code:
-path './do_not*' -prune -o -print
prune / remove any path that contains './do_not*' or print anything else
 
1 members found this post helpful.
Old 03-11-2012, 09:30 AM   #14
sysmicuser
Member
 
Registered: Mar 2010
Posts: 332

Original Poster
Rep: Reputation: 0
@grail.

Thank you very much !

yes I can certainly confirm that
Code:
find -depth -path './do_not*' -prune -o -print
is not omitting do_not* directories...

beautiful logic
 
Old 03-11-2012, 10:23 AM   #15
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,243

Rep: Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684Reputation: 2684
hmmm .. well the only thing I can guess at is that your find may be of a later version and somehow not supporting the options.
Just to show what I have in place for testing:
Code:
$ find
.
./t1
./do_not_delete
./t8
./t6
./do_not_delete_later
./t9
./t9/z2
./t9/z1
./t4
./t5
./t3
./t2
./t2/b1
./t2/b1/b11
./t2/b1/b12
./t2/s1
./t7
./t7/x1
./t7/x1/x11
./t7/x1/x12
$ find -depth -path './do_not*' -prune -o -print
./t1
./t8
./t6
./t9/z2
./t9/z1
./t9
./t4
./t5
./t3
./t2/b1/b11
./t2/b1/b12
./t2/b1
./t2/s1
./t2
./t7/x1/x11
./t7/x1/x12
./t7/x1
./t7
.
 
  


Reply


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 Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to call a array dynamically into a script subbuyt Programming 7 09-08-2011 07:33 AM


All times are GMT -5. The time now is 08:44 AM.

Main Menu
Advertisement
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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration