[SOLVED] Make list of directories which contain files other than subdirs
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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?
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.
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.
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.