|
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]
|
|
| * 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
|
|
|
|
|