LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-17-2009, 11:49 AM   #1
zainka
LQ Newbie
 
Registered: Oct 2009
Posts: 4

Rep: Reputation: 0
Make list of directories which contain files other than subdirs


Hi

I need to, through a bash script, go through a given directory (given as argument 1) to list out the relative path in this directory (including $1) for eact subdirectory which contains files. Directories which only contain . .. and eventually only subdirectories SHALL NOT be listed. It is this last requirement that makes it difficult for me.

I have been using the tree command for now, but I have not found a way to ignore paths to directories which only contains other subdirs or nothing at all in any easy way. I may offcourse test each directory after they are listed but this gives an extra loop to go through and I beleive it should be possible to do it directly when creatring the list.

I guess by using find or ls in conjuntion with the tree command or by itself it should be possible but I am not to conversant of nested script commands.


Any hope?


Breg
Vidar

Last edited by zainka; 10-17-2009 at 11:53 AM.
 
Old 10-17-2009, 11:52 AM   #2
jschiwal
LQ Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682
Try something like
find */ -type d

If the format isn't what you need, look at find's -printf command and it's control string to control exactly how the results are printed.
 
Old 10-17-2009, 11:58 AM   #3
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
How about using a recursively called function to walk the directory tree and print out its path if it is called to work on a directory that contains files?
 
Old 10-17-2009, 02:28 PM   #4
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
So basically, if I understand it right, you want a list of directories that contain files, and you don't want to include ones that contain subdirectories only, even if those subdirectories contain files.

I think this will do it.
Code:
#!/bin/bash

IFS='
'

list="$(find "." -type d ! -empty ! -name ".")"

for d in $list; do

     [[ "$(find $d -maxdepth 1 -type f)" ]] && echo "$d"

done

exit 0
PS: I don't think it's easily possible to do it in a one-liner, since you have to filter for multiple conditions: whether it's empty, whether it contains files, and whether it contains directories.


(Edited upon re-reading OP. I misunderstood the requirements the first time)

Last edited by David the H.; 10-17-2009 at 03:16 PM.
 
Old 10-17-2009, 05:10 PM   #5
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
Another, similar way:
Code:
find /path/to/dir -type d -print | while read D; do
    ls -AF "$D" | grep -q \[^/\]\$ && echo "==$D"
done

Last edited by Hko; 10-17-2009 at 05:13 PM.
 
Old 10-18-2009, 08:03 AM   #6
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
wouldn't

find . ! -type d

do the job?
 
Old 10-18-2009, 04:28 PM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Quote:
Originally Posted by bigearsbilly View Post
wouldn't

find . ! -type d

do the job?
That gives you a list of files. But according to the OP, he wants a list of directories that contain files.

But that does give me an idea for another way to do it:
Code:
find . ! -type d -exec dirname '{}' \;| sort -u
 
Old 10-20-2009, 02:19 AM   #8
zainka
LQ Newbie
 
Registered: Oct 2009
Posts: 4

Original Poster
Rep: Reputation: 0
Hi
Thanks to all for your participation. Through your input I learned a lot, including useful tricks that I can use in other scripts later even though it did not solve this particular problem.

However, Davids final contribution found its way into my script.

I use the script to generate patches of a module in my build. I also added a few parameters since I had to exclude a few folders that else was listed with any of the methods above (and I did not tell that I needed to exclude anything either, so no-one to blame) and my final usage looks like this, for your reference.

Quote:
find * ! -path "*first path to exclude*" ! -path "*second path to exclude*" ! -type d -exec dirname '{}' \; | sort -u >> $ptree
$ptree is just where I store the list listed to be used later in the script.

Thanks to all

Breg
Vidar
 
Old 10-20-2009, 02:20 PM   #9
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Come to think of it, we can make my last suggestion even cleaner. I just remembered that you can use find's -printf function to output the directory path, so we don't need to call on the external dirname command.
Code:
find * ! -path "*first path to exclude*" ! -path "*second path to exclude*" ! -type d -printf "%h\n" | sort -u >> $ptree
Also, filtering with "!-type d" will not filter out non-file entries such as symlinks or pipes. If that's a problem, you'll have to filter them too.
 
Old 10-21-2009, 04:20 AM   #10
zainka
LQ Newbie
 
Registered: Oct 2009
Posts: 4

Original Poster
Rep: Reputation: 0
I tested it and off course it gave the same result, but you knew that already, didn't you As a bonus it also went faster whit printf.

Last edited by zainka; 10-21-2009 at 04:22 AM.
 
  


Reply



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 list the number of files in serveral sub-directories cy163 Linux - Newbie 2 05-16-2009 11:29 AM
Obtaining list of files in all users directories aarontwc Programming 4 12-21-2008 08:08 PM
Is there a way to make certain directories list on top of others with Konqueror? Cinematography Linux - Desktop 2 10-22-2007 10:22 AM
List all files in multiple directories haiders Linux - Newbie 6 05-10-2007 12:05 PM
Getting a list of directories with certain files inside... Banacek Linux - Newbie 7 11-27-2006 05:43 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:35 PM.

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
Open Source Consulting | Domain Registration