With zsh
:
x=42 size=M+1
print -rC1 -- **/*(NFe['()(($#)) $REPLY/*(N.L${size}Y${x}[$x]oN)'])
Would print the directories that contain at least 42 files whose size is strictly greater than 1MiB.
**/*
: recursive globbing
(...)
: glob qualifiers
N
: N
ullglob: don't complain if there's no match
F
: restrict to files of type directory that are F
ull (have at least one entry).
e['code']
: filter files for which the e
valuation of code
returns true.
()(($#)) args
: anonymous function that returns true if the number of its arguments is non-zero
$REPLY
: the file (here directory) currently being considered in code
.
$REPLY/*
: the files in there. Replace with $REPLY/**/*
to also count files in subdirs.
.
: restrict to regular files (exclude directories, symlinks, fifos, devices...).
LM+1
: limits to files whose size rounded up to the next integer number of mebibytes is strictly greater than 1 (files with size 1048577 bytes and above).
Y$x
: stop looking after the xth one has been found as an optimisation.
[$x]
: select the xth in that list (again as an optimisation, so the code
only needs to check it's passed at least one argument).
oN
: don't bother sorting that list.
You can add the D
qualifier to either or both globs if you also want to consider hidden dirs/files.
But if it's to do something with those files afterwards, you'd likely want to do something like:
for dir in **/*(NF); do
large_files=($dir/*(N.LM+1))
(( $#large_files >= 42 )) && do-something-with $large_files
done