Using bash and its globstar shell option. With this option set, the ** glob pattern matches all the pathnames beneath the given directory. This means we don't have to explicitly walk the directory structure in our script:
#!/bin/bash
dir="$1"
size="$2"
shopt -s globstar
for pathname in "$dir"/**; do
[ ! -f "$pathname" ] && continue
filesize=$( wc -c <"$pathname" )
if [ "$filesize" -lt "$size" ]; then
printf 'Found %s, size is %d\n' "$pathname" "$filesize"
fi
done
Rather than writing your own directory tree walker, you may instead use find. The following find command does what your code tries to do:
The only slight difference between the explicit directory walker and the find variation is that find (when used as above) will ignore symbolic links, while the shell function above it will resolve symbolic links, possibly causing directory loops to be traversed infinitely, or the same data to be counted more than once.
Using find, the contents of the files will not be read to figure out the file size. Instead a lstat() library call will be made to query the filesystem for the file's size. This is many times faster than using wc -c!
On most (but not all) Unices, you may also use the command line utility stat to get the file size. See the manual for this utility on your system for how to use it (it works differently on Linux and BSD).