Your first loop sorts the single line output of each wc -l
individually, and outputs that one after the other. Doesn't work (and that's expected!).
Your second approach first aggregates all lines from all wc
calls, and then sorts them: that's the right way to go. Whether or not there's a file in between is not the problem here – the problem is that in your first loop you're not actually sorting anything.
So,
( for path in $paths; do
wc -l $path
done ) | sort -n
should work.
Your find
call is strange in that it uses egrep to filter the output (which will lead to interesting results the way you do it with folders that end in .cpp, as you'll sometimes find them in e.g. CMake builds) instead of simply find -type f '(' -iname '*.cpp' -o -iname '*.h' ')'
; however, I'd discourage you from using find
here alltogether, because file names with spaces (extremely common), newlines etc will break all this, for no good reason.
Instead, use what your shell (which I guess is bash) gives you directly:
shopt -s nullglob ## don't fail on empty globs
shopt -s globstar
for path in /.{h,cpp} ; do
wc -l "${path}"
done | sort -n
We can make this even shorter, in fact:
shopt -s nullglob ## don't fail on empty globs
shopt -s globstar
wc -l **/*.{h,cpp} | sort -n