I know I can do this to get a list of directories inside /vz/root:

find /vz/root/ -type d -maxdepth 1 -exec echo {} \;

But how can I edit this to only list the directories that do not contain a subdirectory called "php-5.3.3"? So if there's 3 directories /vz/root/101, /vz/root/102, and /vz/root/103, and two of them contain php-5.3.3 subdirectory, it would only echo the path of the one that doesn't have it.

link|improve this question
feedback

4 Answers

up vote 2 down vote accepted

Try

find /vz/root/ -maxdepth 1 -type d  \! -exec test -d '{}/php-5.3.3' \; -print | grep -v php-5.3.3 | uniq -w 12 | grep -v '^/vz/root/$'
link|improve this answer
Thank you! I added maxdepth to your command and it worked perfectly. I was getting loads of errors without the maxdepth. find /vz/root/ -maxdepth 1 -type d \! -exec test -d '{}/php-5.3.3' \; -print | grep -v php-5.3.3 | uniq -w 12 | grep -v '^/vz/root/$' – Tim Nov 2 '10 at 10:09
What was the error ? – Iain Nov 2 '10 at 10:17
Something like proc/101 not found, repeated with all the different numbers from /vz/root – Tim Nov 2 '10 at 10:30
Fun! 1) This is why the -exec test in find exists, kudos for the excellent use. 2) It wasn't clear to me that the original problem was intended to be used on the root of a filesystem. You might also use -xdev to prevent the search from searching the proc (or dev, or sys, or tmp, or NFS, or other) filesystem. – Slartibartfast Nov 3 '10 at 4:21
feedback

If you want to exclude the paths that contain php-5.3.3, you can simply use grep -v

find /root/ -maxdepth 1 -type d -exec echo {} \; | grep -v php-5.3.3
link|improve this answer
This doesn't actually work because php-5.3.3 is a subdirectory. I am searching in /vz/root but php-5.3.3 is inside eg /vz/root/101/php-5.3.3 – Tim Nov 2 '10 at 9:34
I could do it with maxdepth 2, but then I will also need to exclude all the other directory names that I'm not interested in. How would I specify multiple names with grep? – Tim Nov 2 '10 at 9:36
"How would I specify multiple names with grep?" -- use egrep. For example, egrep -v "(first_name|second_name|third_name)" – Janne Pikkarainen Nov 2 '10 at 10:14
feedback

You can use ! as not operator.

find /vz/root/ -type d -maxdepth 1 ! -ipath '*php-5.3.3*' -exec echo {} \;

That would list all the directories under /vz/root/ except the ones that has php-5.3.3 in their path name.

link|improve this answer
This doesn't actually work because php-5.3.3 is a subdirectory. I am searching in /vz/root but php-5.3.3 is inside eg /vz/root/101/php-5.3.3. If I run this it's just listing all the directories in /vz/root regardless of whether they contain the php-5.3.3 subdir. – Tim Nov 2 '10 at 10:02
1  
Damn, you're right. This one is actually a harder piece to solve than I originally thought. Time to spawn a voodoo doll ... – Janne Pikkarainen Nov 2 '10 at 10:18
feedback

It is possible to take something that almost solves it with find and use find2perl to create a Perl program that does the same thing. Then modify the Perl script to do something advanced. I won't enumerate though because you asked for a variation on the find command and this is outside the scope of your request. Plus, you'd have to know some Perl and I don't want to start a flamewar.

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.