Unix Shell - Find empty dirs

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > November 2006 > Find empty dirs





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Find empty dirs
* Tong *

2006-11-27, 1:29 am

Hi,

Is there any way to find which dir (under cwd) is empty? I.e., has no
file in it but may have sub dirs?

thanks

--
Tong (remove underscore(s) to reply)
http://xpt.sourceforge.net/


--
Posted via a free Usenet account from http://www.teranews.com

Kaz Kylheku

2006-11-27, 1:29 am

* Tong * wrote:
> Is there any way to find which dir (under cwd) is empty? I.e., has no
> file in it but may have sub dirs?


Here is one way. Note that this is breaks if there are paths with
spaces in them:

find . -type d -exec sh -c '[ -z "$(find '{}' -maxdepth 1 ! -type d
-print)" ]' \; -print

* Tong *

2006-11-28, 1:32 am

On Sun, 26 Nov 2006 21:51:03 -0800, Kaz Kylheku wrote:

>
> Here is one way. Note that this is breaks if there are paths with
> spaces in them:
>
> find . -type d -exec sh -c '[ -z "$(find '{}' -maxdepth 1 ! -type d
> -print)" ]' \; -print


Thanks, that works.

May I know why it will break when there are spaces in path name?

find: ./af/empty: No such file or directory
find: dir: No such file or directory
../af/empty dir

I saw that the {} has been quoted with ''. Why is the quote ignored?

thanks

--
Tong (remove underscore(s) to reply)
http://xpt.sourceforge.net/


--
Posted via a free Usenet account from http://www.teranews.com

Bill Marcum

2006-11-28, 1:32 am

On Mon, 27 Nov 2006 22:25:29 -0500, * Tong *
<sun_tong_001@users.sourceforge.net> wrote:
> On Sun, 26 Nov 2006 21:51:03 -0800, Kaz Kylheku wrote:
>
>
> Thanks, that works.
>
> May I know why it will break when there are spaces in path name?
>
> find: ./af/empty: No such file or directory
> find: dir: No such file or directory
> ./af/empty dir
>
> I saw that the {} has been quoted with ''. Why is the quote ignored?
>

The {} is not inside single quotes.
'[ -z "$(find '
{}
' -maxdepth 1 ! -type d -print)" ]'


--
Ginger snap.
Kaz Kylheku

2006-11-28, 1:32 am


* Tong * wrote:
> On Sun, 26 Nov 2006 21:51:03 -0800, Kaz Kylheku wrote:
>
>
> Thanks, that works.
>
> May I know why it will break when there are spaces in path name?
>
> find: ./af/empty: No such file or directory
> find: dir: No such file or directory
> ./af/empty dir
>
> I saw that the {} has been quoted with ''. Why is the quote ignored?


That's a mistake. Note that the entire argument to sh -c is in single
quotes. So these inner quotes break that up into two single-quoted
pieces with {} in the middle. It doesn't matter if you remove these;
either way, it breaks.

To fix the problem, you have to get {} to be quoted. Here is how.
Switch to double quotes, and then escape them within. Command expansion
takes place now so you have to escape that too, you want the embedded
sh -c to evaluate the $(find ...), not the outer command:

find . -type d -exec sh -c "[ -z \"\$(find \"{}\" -maxdepth 1 ! -type d
-print)\" ]" \; -print

The real challenge would be protecting this against expansions of {}
which look like a predicate, valid or otherwise.

* Tong *

2006-11-28, 7:24 pm

On Mon, 27 Nov 2006 21:16:23 -0800, Kaz Kylheku wrote:

> To fix the problem, you have to get {} to be quoted. Here is how.
> Switch to double quotes, and then escape them within. Command expansion
> takes place now so you have to escape that too, you want the embedded
> sh -c to evaluate the $(find ...), not the outer command:
>
> find . -type d -exec sh -c "[ -z \"\$(find \"{}\" -maxdepth 1 ! -type d
> -print)\" ]" \; -print


Hi, thank you Kaz for the detailed explanation.

FYI, I found the following sufficient enough under Linux, in which sh is
actually bash:

$ find . -type d -exec sh -c '[ -z "$(find "'{}'" -maxdepth 1 ! -type d -print)" ]' \; -print
./af/empty dir
./af/empty dir/subd

thanks

--
Tong (remove underscore(s) to reply)
http://xpt.sourceforge.net/


--
Posted via a free Usenet account from http://www.teranews.com

Stephane CHAZELAS

2006-11-28, 7:24 pm

2006-11-28, 16:13(-05), * Tong *:
> On Mon, 27 Nov 2006 21:16:23 -0800, Kaz Kylheku wrote:
>
>
> Hi, thank you Kaz for the detailed explanation.
>
> FYI, I found the following sufficient enough under Linux, in which sh is
> actually bash:
>
> $ find . -type d -exec sh -c '[ -z "$(find "'{}'" -maxdepth 1 ! -type d -print)" ]' \; -print
> ./af/empty dir
> ./af/empty dir/subd

[...]

Note that there is nothing bash specific above. -maxdepth is GNU
(or FreeBSD) find specific though.

find . -type d -exec sh -c '[ -z "$(find {} -maxdepth 1 ! -type d -print)" ]' \; -print

is enough.

With zsh, you could do:

has_no_file() {
! { : $1/*(D^/oN[1]) } 2> /dev/null
}
print -rl -- **/*(D/+has_no_file)

--
Stéphane
* Tong *

2006-11-28, 7:24 pm

On Tue, 28 Nov 2006 21:41:47 +0000, Stephane CHAZELAS wrote:

>
> find . -type d -exec sh -c '[ -z "$(find {} -maxdepth 1 ! -type d
> -print)" ]' \; -print


Thanks for the input Stephane, but you missed the gist of the discussion:

> Note that this is breaks if there are paths with
> spaces in them.


--
Tong (remove underscore(s) to reply)
http://xpt.sourceforge.net/


--
Posted via a free Usenet account from http://www.teranews.com

Stephane CHAZELAS

2006-11-29, 7:28 am

2006-11-28, 19:15(-05), * Tong *:[vbcol=seagreen]
> On Tue, 28 Nov 2006 21:41:47 +0000, Stephane CHAZELAS wrote:
>
>
> Thanks for the input Stephane, but you missed the gist of the discussion:
>
[...]

Indeed. But the '' that were there were of no use as they were
closing the outer ones. It should be:

find . -type d -exec sh -c '
[ -z "$(find "$1" -maxdepth 1 ! -type d -print)" ]
' {} {} \; -print


--
Stéphane
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com