If you want a line-count for each individual file:
find . -type f -exec wc -l {} + | awk '! /^[ 0-9]+[[:space:]]+total$/'
I've excluded the total lines because there will be several of them with this many files being processed. The find ... -exec ... +
will try to fit as many filenames onto a single command line as possible, but that will be a LOT less than 119766 files....probably only several thousand (at most) per invocation of wc
, and each one will result in its own independent 'total' line.
If you want the total number of lines in all files combined, here's one way of doing it:
find . -type f -exec wc -l {} + |
awk '/^[ 0-9]+[[:space:]]+total$/ {print $1}' |
xargs | sed -e 's/ /+/g' | bc
This prints only the line counts on the total lines, pipes that into xargs
to get the counts all on one line, then sed to transform the spaces into +
signs, and then pipes the lot into bc
to do the calculation.
Example output:
$ cd /usr/share/doc
$ find . -type f -exec wc -l {} + |
awk '/^[ 0-9]+[[:space:]]+total$/ {print $1}' |
xargs | sed -e 's/ /+/g' | bc
53358931
Update 2022-05-05
It is better to run wc -l
via sh
. This avoids the risk of problems arising if any of the filenames are called total
....aside from the total line being the last line of wc
's output, there is no way to distinguish an actual total line from the output for a file called "total", so a simple awk script that matches "total" can't work reliably.
To show counts for individual files, excluding totals:
find . -type f -exec sh -c 'wc -l "$@" | sed "\$d"' sh {} +
This runs wc -l
on all filenames and deletes the last line (the "total" line) from each batch run by -exec
.
The $d
in the sed script needs to be escaped because the script is in a double-quoted string instead of the more usual single-quoted string. double-quotes were used because the entire sh -c
is a single-quoted string. It's easier and more readable to just escape one $
symbol than to use '\''
to fake embedding a single-quote inside a single quote.
To show only the totals:
find . -type f -exec sh -c 'wc -l "$@" | awk "END {print \$1}"' sh {} + |
xargs | sed -e 's/ /+/g' | bc
Instead of using sed
to delete the last line from each batch of files passed to wc
via sh
by find ... -exec
, this uses awk
to print only the last lines (the "total") from each batch. The output of find
is then converted to a single line (xargs) with +
characters between each number (sed to transform spaces to +), and then piped into bc
to perform the calculation.
Just like the $d
in the sed script, the $1
in the awk script needs to be escaped because of double-quoting.
ls, cat, mv
and other commands have this limitations. As the error already tells you, you are providing too many arguments to thecat
command in this case. Usegetconf -a |grep MAX_ARG
to see the MAX_ARG value that applies to your kernel.