bug-findutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to find directories that only contain a certain type of files (e


From: Peng Yu
Subject: Re: How to find directories that only contain a certain type of files (e.g., .txt)?
Date: Fri, 15 Sep 2023 10:24:33 -0500

On Tue, Sep 12, 2023 at 6:13 PM raf <gnu@raf.org> wrote:
>
> On Tue, Sep 12, 2023 at 06:39:32PM +0200, Andreas Metzler <gnu@bebt.de> wrote:
>
> > On 2023-09-12 Peng Yu <pengyu.ut@gmail.com> wrote:
> > > Hi,
> >
> > > How to find directories that only contain a certain type of files (e.g., 
> > > .txt)?
> >
> > > One idea that I have is to just search for all files' paths. Then use
> > > a post-processing script to analyze which directories only contain
> > > files of a certain type (e.g., .txt extension).
> >
> > > Does anybody have a better idea of how to do this search?
> >
> > find -name '*.txt' -printf '%h\n' | sort -u
> >
> > (Actually you should use \0 and sort -u --zero-terminated and work on
> > that nul-terminated list.)
> >
> > cu Andreas
>
> That will list directories that contain .txt files,
> not directories that *only* contain .txt files.
>
> This should do it (assuming filenames without newlines):
>
>   find . -type d -exec sh -c '[ "$(find {} -mindepth 1 -maxdepth 1 | wc -l)" 
> = "$(find {} -mindepth 1 -maxdepth 1 -type f -name "*.txt" | wc -l)" ]' \; 
> -print
>
> It lists directories that contain only *.txt files (i.e. no other
> files and no subdirectories). If it needs to ignore subdirectories
> and only exclude non-.txt files:
>
>   find . -type d -exec sh -c '[ "$(find {} -mindepth 1 -maxdepth 1 -type f | 
> wc -l)" = "$(find {} -mindepth 1 -maxdepth 1 -type f -name "*.txt" | wc -l)" 
> ]' \; -print
>
> But even that's not complete. It'll report empty directories (because 0 == 
> 0), so:
>
>   find . -type d -exec sh -c \ '[ "$(find {} -mindepth 1 -maxdepth 1 -type f 
> -name "*.txt" | wc -l)" -gt 0 ] && [ "$(find {} -mindepth 1 -maxdepth 1 -type 
> f | wc -l)" = "$(find {} -mindepth 1 -maxdepth 1 -type f -name "*.txt" | wc 
> -l)" ]' \; -print

This is too inefficient. It will call sh too many times.

To be efficient, I will have to call find to just get the path of all
files and process the output with another text processing program like
awk?

-- 
Regards,
Peng



reply via email to

[Prev in Thread] Current Thread [Next in Thread]