Berlin Brown
Berlin Brown

Reputation: 11734

Use find, wc, and sed to count lines

I was trying to use sed to count all the lines based on a particular extension.

find -name '*.m' -exec wc -l {} \; | sed ...

I was trying to do the following, how would I include sed in this particular line to get the totals.

Upvotes: 30

Views: 52207

Answers (8)

Alexei Polkhanov
Alexei Polkhanov

Reputation: 599

On modern GNU platforms wc and find take -print0 and -files0-from parameters that can be combined into a command that count lines in files with total at the end. Example:

find . -name '*.c' -type f -print0 | wc -l --files0-from=-

Upvotes: 5

Daniel James
Daniel James

Reputation: 3939

Most of the answers here won't work well for a large number of files. Some will break if the list of file names is too long for a single command line call, others are inefficient because -exec starts a new process for every file. I believe a robust and efficient solution would be:

find . -type f -name "*.m" -print0 | xargs -0 cat | wc -l

Using cat in this way is fine, as its output is piped straight into wc so only a small amount of the files' content is kept in memory at once. If there are too many files for a single invocation of cat, cat will be called multiple times, but all the output will still be piped into a single wc process.

Upvotes: 19

geoffry
geoffry

Reputation:

For big directories we should use:

find . -type f -name '*.m' -exec sed -n '$=' '{}' + 2>/dev/null | awk '{ total+=$1 }END{print total}' 

# alternative using awk twice
find . -type f -name '*.m' -exec awk 'END {print NR}' '{}' + 2>/dev/null | awk '{ total+=$1 }END{print total}' 

Upvotes: 1

marco
marco

Reputation: 4675

sed is not the proper tool for counting. Use awk instead:

find . -name '*.m' -exec awk '{print NR}' {} +

Using + instead of \; forces find to call awk every N files found (like with xargs).

Upvotes: 1

igustin
igustin

Reputation: 1118

Hm, solution with cat may be problematic if you have many files, especially big ones.

Second solution doesn't give total, just lines per file, as I tested.

I'll prefer something like this:

find . -name '*.m' | xargs wc -l | tail -1

This will do the job fast, no matter how many and how big files you have.

Upvotes: 3

dfa
dfa

Reputation: 116334

you could use sed also for counting lines in place of wc:

 find . -name '*.m' -exec sed -n '$=' {} \;

where '$=' is a "special variable" that keep the count of lines

EDIT

you could also try something like sloccount

Upvotes: 4

Emmanuel BERNAT
Emmanuel BERNAT

Reputation: 816

You may also get the nice formatting from wc with :

wc `find -name '*.m'`

Upvotes: 57

sth
sth

Reputation: 229593

You can cat all files through a single wc instance to get the total number of lines:

find . -name '*.m' -exec cat {} \; | wc -l

Upvotes: 6

Related Questions