Use wc on all subdirectories to count the sum of lines
You probably want this:
find . -type f -print0 | wc -l --files0-from=-
If you only want the total number of lines, you could use
find . -type f -exec cat {} + | wc -l
How can I count all the lines of code in a directory recursively?
Try:
find . -name '*.php' | xargs wc -l
or (when file names include special characters such as spaces)
find . -name '*.php' | sed 's/.*/"&"/' | xargs wc -l
The SLOCCount tool may help as well.
It will give an accurate source lines of code count for whatever
hierarchy you point it at, as well as some additional stats.
Sorted output:
find . -name '*.php' | xargs wc -l | sort -nr
How to count lines of code including sub-directories
First you do not need to use cat
to count lines. This is an antipattern called Useless Use of Cat (UUoC). To count lines in files in the current directory, use wc
:
wc -l *
Then the find
command recurses the sub-directories:
find . -name "*.c" -exec wc -l {} \;
.
is the name of the top directory to start searching from-name "*.c"
is the pattern of the file you're interested in-exec
gives a command to be executed{}
is the result of the find command to be passed to the command (herewc-l
)\;
indicates the end of the command
This command produces a list of all files found with their line count, if you want to have the sum for all the files found, you can use find to list the files (with the -print
option) and than use xargs to pass this list as argument to wc-l.
find . -name "*.c" -print | xargs wc -l
EDIT to address Robert Gamble comment (thanks): if you have spaces or newlines (!) in file names, then you have to use -print0
option instead of -print
and xargs -null
so that the list of file names are exchanged with null-terminated strings.
find . -name "*.c" -print0 | xargs -0 wc -l
The Unix philosophy is to have tools that do one thing only, and do it well.
Total number of lines in a directory
If what you want is the total number of lines and nothing else, then I would suggest the following command:
cat * | wc -l
This catenates the contents of all of the files in the current working directory and pipes the resulting blob of text through wc -l
.
I find this to be quite elegant. Note that the command produces no extraneous output.
UPDATE:
I didn't realize your directory contained so many files. In light of this information, you should try this command:
for file in *; do cat "$file"; done | wc -l
Most people don't know that you can pipe the output of a for
loop directly into another command.
Beware that this could be very slow. If you have 100,000 or so files, my guess would be around 10 minutes. This is a wild guess because it depends on several parameters that I'm not able to check.
If you need something faster, you should write your own utility in C. You could make it surprisingly fast if you use pthreads.
Hope that helps.
LAST NOTE:
If you're interested in building a custom utility, I could help you code one up. It would be a good exercise, and others might find it useful.
How to count number of files in each directory?
Assuming you have GNU find, let it find the directories and let bash do the rest:
find . -type d -print0 | while read -d '' -r dir; do
files=("$dir"/*)
printf "%5d files in directory %s\n" "${#files[@]}" "$dir"
done
Recursively go through directories and files in bash + use wc
Yes, you can use find
:
$ find DIR -iname "regex" -type f -exec wc -l '{}' \;
Or, if you want to count the total number of lines, in all files:
$ find DIR -iname "regex" -type f -exec wc -l '{}' \; | awk '{ SUM += $1 } END { print SUM }'
Your script would then look like:
#!/bin/bash
# $1 - name of the directory - first argument
# $2 - regex - second argument
if [ $# -lt 2 ]; then
echo Usage: ./myscript.sh DIR "REGEX"
exit
fi
find "$1" -iname "$2" -type f -exec wc -l '{}' \;
Edit: - if you need more fancy regular expressions, use -regextype posix-extended
and -regex
instead of -iname
as noted by @sudo_O in his answer.
Related Topics
How to Get Notified for Ip Address Changes Automatically
Difference Between .Dynamic .Dynsym and .Dynstr in an Elf Executable
Grep String Inside Double Quotes
Iterating Over Lists in Makefiles
Cannot Create Backup File(Add ! to Overwrite)
How to Know Which Device Is Connected in Which /Dev/Ttyusb Port
Prepend Data from One File to Another
Cannot Install Extensions in Visual Studio Code
Linux Find Out Hyper-Threaded Core Id
Getting Exit Status Code from 'Ftp' Command in Linux Shell
How to Capture Network Frames in a Kernel Module
How to Calculate the Total Size of Certain Files Only, Recursive, in Linux
Insert Linux Kernel Module Statically