3

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.

5 Answers 5

8

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/$'
4
  • 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, 2010 at 10:09
  • What was the error ?
    – user9517
    Nov 2, 2010 at 10:17
  • Something like proc/101 not found, repeated with all the different numbers from /vz/root
    – Tim
    Nov 2, 2010 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. Nov 3, 2010 at 4:21
2

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
3
  • 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, 2010 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, 2010 at 9:36
  • "How would I specify multiple names with grep?" -- use egrep. For example, egrep -v "(first_name|second_name|third_name)" Nov 2, 2010 at 10:14
1

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.

2
  • 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, 2010 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 ... Nov 2, 2010 at 10:18
0

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.

0

Simplified version of the accepted answer:

find /vz/root/ -type d -maxdepth 1 -exec test ! -d "{}/php-5.3.3" \; -print

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .