On Tue, Sep 12, 2023 at 6:13 PM raf <g...@raf.org> wrote: > > On Tue, Sep 12, 2023 at 06:39:32PM +0200, Andreas Metzler <g...@bebt.de> > wrote: > > > On 2023-09-12 Peng Yu <pengyu...@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