[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