cloc(1)
Okay so bestie, you found the cloc(1) page and I'm about to make it make sense โ this is the User Commands manual for cloc, and it's lowkey iconic. Grab a strawberry ๐ and let's go.
โจ NAME โจ
cloc โ Count, or compute differences of, lines of source code and comments.
๐ฆ SYNOPSIS ๐ฆ
cloc [options] <FILE|DIR> ...
๐ DESCRIPTION ๐
It counts โ or computes the differences of โ physical lines of source code in the files you hand it (and yeah, those files can be archives like compressed tarballs or zip files, or even git commit hashes or branch names ๐) and/or recursively below the directories you give it.
And the vibe? It's written entirely in Perl, using only modules from the standard distribution. No cap, that's the whole dependency story. ๐
๐ธ OPTIONS ๐ธ
๐ Input Options ๐
To count standard input, use the special filename - and either --stdin-name=FILE to tell cloc the name of the file being piped in, or --force-lang=LANG to apply the LANG counter to all input. Fr fr, that's your stdin situation.
--extract-with=CMDโ You only need this one if cloc can't figure out by itself how to extract the contents of the input file(s). UseCMDto extract binary archive files (e.g.:.tar.gz,.zip,.Z). Use the literal>FILE<as a stand-in for the actual file(s) to be extracted.
For example, to count lines of code in the input files gcc-4.2.tar.gz perl-5.8.8.tar.gz on Unix use:
--extract-with='gzip -dc >FILE< | tar xf -
or, if you have GNU tar:
--extract-with='tar zxf >FILE<'
and on Windows, use, for example:
--extract-with="\"c:\Program Files\WinZip\WinZip32.exe\" -e -o >FILE<
--list-file=FILEโ Takes the list of file and/or directory names to process fromFILE, which has one file/directory name per line. Only exact matches are counted; relative path names will be resolved starting from the directory where cloc is invoked. SetFILEto-to read file names from a STDIN pipe. See also--exclude-list-file,--config.--diff-list-file=FILEโ Takes the pairs of file names to be diff'ed fromFILE, whose format matches the output of--diff-alignment. (Run with that option to see a sample.) The language identifier at the end of each line is ignored. This enables--diffmode and by-passes file pair alignment logic. See also--config.--vcs=VCSโ Invokes a system call toVCSto obtain a list of files to work on. IfVCSis'git', then it will invoke'git ls-files'to get a file list and'git submodule status'to get a list of submodules whose contents will be ignored. See also--gitwhich accepts git commit hashes and branch names. IfVCSis'svn'then it will invoke'svn list -R'. The primary benefit is that cloc will then skip files explicitly excluded by the versioning tool in question, ie, those in.gitignoreor have thesvn:ignoreproperty. AlternativelyVCSmay be any system command that generates a list of files.
Note: cloc must be in a directory which can read the files as they are returned byVCS. cloc will not download files from remote repositories.'svn list -R'may refer to a remote repository to obtain file names (and therefore may require authentication to the remote repository), but the files themselves must be local.
Setting VCS to 'auto' selects between 'git' and 'svn' (or neither) depending on the presence of a .git or .svn subdirectory below the directory where cloc is invoked.
--unicodeโ Checks binary files to see if they contain Unicode expanded ASCII text. Heads up bestie, this causes performance to drop noticeably. ๐ญ
๐ Processing Options ๐
--autoconfโ Counts.infiles (as processed by GNU autoconf) of recognized languages. See also--no-autogen.--by-fileโ Reports results for every source file encountered.--by-file-by-langโ Reports results for every source file encountered in addition to reporting by language.--config FILEโ Reads command line switches fromFILEinstead of the default location of~/.config/cloc/options.txt. The file should contain one switch, along with arguments (if any), per line. Blank lines and lines beginning with'#'are skipped. Options given on the command line take priority over entries read from the file. If a directory is also given with any of these switches:--list-file,--exclude-list-file,--read-lang-def,--force-lang-def,--diff-list-fileand a config file exists in that directory, it will take priority over~/.config/cloc/options.txt.--count-and-diff SET1 SET2โ First performs direct code counts of source file(s) ofSET1andSET2separately, then performs a diff of these. Inputs may be pairs of files, directories, or archives. If--outor--report-fileis given, three output files will be created, one for each of the two counts and one for the diff. See also--diff,--diff-alignment,--diff-timeout,--ignore-case,--ignore-whitespace.--diff SET1 SET2โ Computes differences in code and comments between source file(s) ofSET1andSET2. The inputs may be pairs of files, directories, or archives. Use--diff-alignmentto generate a list showing which file pairs where compared. See also--count-and-diff,--diff-alignment,--diff-timeout,--ignore-case,--ignore-whitespace.--diff-timeout Nโ Ignores files which take more thanNseconds to process. Default is 10 seconds. SettingNto0allows unlimited time. (Large files with many repeated lines can causeAlgorithm::Diff::sdiff()to take hours. ๐)--docstring-as-codeโ cloc considers docstrings to be comments, but this is not always correct as docstrings represent regular strings when they appear on the right hand side of an assignment or as function arguments. This switch forces docstrings to be counted as code.--follow-linksโ[Unix only]Follow symbolic links to directories (sym links to files are always followed).--force-lang=LANG[,EXT]โ Processes all files that have aEXTextension with the counter for languageLANG. For example, to count all.ffiles with the Fortran 90 counter (which expects files to end with.f90) instead of the default Fortran 77 counter, use:
--force-lang="Fortran 90",f
If EXT is omitted, every file will be counted with the LANG counter. This option can be specified multiple times (but that is only useful when EXT is given each time). See also --script-lang, --lang-no-ext.
--force-lang-def=FILEโ Loads language processing filters fromFILE, then uses these filters instead of the built-in filters.
Note: languages which map to the same file extension (for example: MATLAB/Objective-C/MUMPS; Pascal/PHP; Lisp/OpenCL; Lisp/Julia; Perl/Prolog) will be ignored as these require additional processing that is not expressed in language definition files.
Use --read-lang-def to define new language filters without replacing built-in filters (see also --write-lang-def, --write-lang-def-incl-dup).
--gitโ Forces the inputs to be interpreted as git targets (commit hashes, branch names, et cetera) if these are not first identified as file or directory names. This option overrides the--vcs=gitlogic if this is given; in other words,--gitgets its list of files to work on directly from git using the hash or branch name rather than from'git ls-files'. This option can be used with--diffto perform line count diffs between git commits, or between a git commit and a file, directory, or archive. Use-v/--verboseto see the git system commands cloc issues.--git-diff-relโ Same as--git --diff, or just--diffif the inputs are recognized as git targets. Only files which have changed in either commit are compared.--git-diff-allโ Git diff strategy #2: compare all files in the repository between the two commits.--ignore-whitespaceโ Ignores horizontal white space when comparing files with--diff. See also--ignore-case.--ignore-caseโ Ignores changes in case within file contents; consider upper- and lowercase letters equivalent when comparing files with--diff. See also--ignore-whitespace.--ignore-case-extโ Ignores case of file name extensions.
Heads up: this will cause problems counting some languages (specifically,.cand.Care associated with C and C++; this switch would count.Cfiles as C rather than C++ on *nix operating systems). File name case insensitivity is always true on Windows.
--ignore-regexโ Ignores lines in source files that match the given Perl regular expression for the given language(s). This option can be specified multiple times. Language names are comma separated and are followed by the pipe character and the regular expression. Use*to match all languages. Examples:
--ignore-regex='C,Java,C++|^\s*[{};]\s*$'
--ignore-regex='*|DEBUG|TEST\s+ONLY'
These filters are applied after comments are removed. Use --strip-comments=EXT to create new files that show these filters applied. The primary use case is to ignore lines containing only braces, brackets, or puctuation.
--include-submodulesโ When using--vcs=git, include files in git submodules.--lang-no-ext=LANGโ Counts files without extensions using theLANGcounter. This option overrides internal logic for files without extensions (where such files are checked against known scripting languages by examining the first line for"#!"). See also--force-lang,--script-lang.--max-file-size=MBโ Skips files larger than"MB"megabytes when traversing directories. By default,"MB"=100. cloc's memory requirement is roughly twenty times larger than the largest file so running with files larger than100 MBon a computer with less than2 GBof memory will cause problems.
Note: this check does not apply to files explicitly passed as command line arguments.
--no-autogen[=list]โ Ignores files generated by code-production systems such as GNU autoconf. To see a list of these files (then exit), run with--no-autogen listSee also--autoconf.--no-recurseโ Counts files in the given directories without recursively descending below them.--only-count-filesโ Only counts files by language. Blank, comment, and code counts will be zero.--original-dirโ Only effective in combination with--strip-comments. Writes the stripped files to the same directory as the original files.--read-binary-filesโ Processes binary files in addition to text files.
This is usually a bad idea and should only be attempted with text files that have embedded binary data. ๐
okay that's the first chunk, keep scrolling bestie, there's more ๐
--read-lang-def=FILEโ pulls brand new language processing filters out ofFILEand merges them with the ones cloc already knows. IfFILEdefines a language cloc already knows, cloc's own definition wins, periodt. Wanna override cloc's takes? That's--force-lang-def's whole job. (peep--write-lang-deftoo ๐ )--script-lang=LANG,Sโ counts every file that invokesSas a#!scripting language using the counter for languageLANG. So like, files starting with#!/usr/local/bin/perl5.8.8get counted with the Perl counter when you do this:
--script-lang=Perl,perl5.8.8
The language name is case insensitive but the script language executable name S must have the right case โ no cap, it's picky like that ๐ญ. This option can be specified multiple times. See also --force-lang.
--sdir=DIRโ useDIRas the scratch directory instead of letting File::Temp pick where to go. Heads up bestie: files written here are not removed at the end of the run (unlike File::Temp's whole thing). ๐--skip-leading=N[,ext]โ skips the first N lines of each file. And if you also hand it a comma separated list of extensions, it only skips lines from those file types. Example:
--skip-leading=10,cpp,h
will skip the first ten lines of *.cpp and *.h files. Obsessed, honestly โ perfect for ignoring boilerplate text ๐
--skip-uniquenessโ skips the file uniqueness check. Glow-up in performance โจ but at the expense of counting files with identical contents multiple times (if such duplicates exist). Choose your fighter.--statโ okay so some file systems (AFS,CD-ROM,FAT,HPFS,SMB) don't have directory'nlink'counts that match the number of their subdirectories, which means cloc may undercount or completely skip the contents of those file systems ๐. This switch forces File::Find to stat directories to get the correct count. Downside: file search speed will decrease. See also--follow-links.--stdin-name=FILEโ counts lines streamed viaSTDINas if they came from a file namedFILE.--strip-code=EXTโ for each file processed, writes to the current directory a version of the file with blank and code lines removed. The name of each stripped file is the original file name with.EXTappended to it. It's written to the current directory unless--original-diris on.--strip-comments=EXTโ for each file processed, writes to the current directory a version with blank and commented lines removed (in-line comments persist, just so you know). Each stripped file gets.EXTappended to its original name. Same deal: written to the current directory unless--original-diris on.--strip-str-commentsโ replaces comment markers embedded in strings with'xx'. This attempts to work around a limitation in Regexp::Common::Comment where comment markers embedded in strings get seen as actual comment markers and not strings, often resulting in a'Complex regular subexpression recursion limit'warning and incorrect counts ๐ญ. Two disadvantages to using this switch, fr fr:1/code count performance drops, and2/code generated with--strip-commentswill contain different strings where ever embedded comments are found.--sum-reportsโ the input arguments are report files previously created with the--report-fileoption. Makes a cumulative set of results containing the sum of data from the individual report files. Math but make it cute ๐งฎโจ--timeout=Nโ ignores files that take more than N seconds to process at any of the language's filter stages. The default maximum number of seconds spent on a filter stage is the number of lines in the file divided by one thousand. SettingNto0allows unlimited time. See also--diff-timeout.--processes=NUMโ [Available only on systems with a recent version of theParallel::ForkManagermodule. Not available on Windows.] Sets the maximum number of cores cloc uses. The default value of0disables multiprocessing. Multi-core era, slay ๐ฅ--unixโ over-rides the operating system detection logic and runs in UNIX mode. See also--windows,--show-os.--use-sloccountโ if SLOCCount is installed, use its compiled executablesc_count,java_count,pascal_count,php_count, andxml_countinstead of cloc's counters. SLOCCount's compiled counters are substantially faster than cloc's and may give a performance improvement when counting projects with large files. BUT โ ๏ธ these cloc-specific features will not be available:--diff,--count-and-diff,--strip-comments,--unicode.--windowsโ over-rides the operating system detection logic and runs in Microsoft Windows mode. See also--unix,--show-os.
๐ฆ Filter Options ๐ฆ
--include-content=REGEXโ only counts files containing text that matches the given regular expression.--exclude-content=REGEXโ excludes files containing text that matches the given regular expression.--exclude-dir=DIR1[,DIR2 ...]โ excludes the given comma separated directories from being scanned. Like:
--exclude-dir=.cache,test
will skip all files that match "/.cache/" or "/test/" as part of their path. Directories named .bzr, .cvs, .hg, .git, and .svn are always excluded. This option only works with individual directory names so including file path separators is not allowed ๐
โโ๏ธ. Use --fullpath and --not-match-d=REGEX to supply a regex matching multiple subdirectories.
--exclude-ext=EXT1[,EXT2 ...]โ do not count files having the given file name extensions.--exclude-lang=L1[,L2[...]]โ excludes the given comma separated languages from being counted.--exclude-list-file=FILEโ ignores files and/or directories whose names appear inFILE.FILEshould have one file name per line. Only exact matches are ignored; relative path names will be resolved starting from the directory where cloc is invoked. See also--list-file,--config.--fullpathโ modifies the behavior of--match-for--not-match-fto include the file's path in the regex, not just the file's basename. (This does not expand each file to include its absolute path โ instead it uses as much of the path as is passed in to cloc.)--include-ext=<ext1[,ext2[...]]>โ counts only languages having the given comma separated file extensions. Use--show-extto see the recognized extensions.--include-lang=L1[,L2 ...]โ counts only the given comma separated, case-insensitive languagesL1,L2,L3, et cetera.--match-d=REGEXโ only counts files in directories matching the Perl regex. For example
--match-d='/(src|include)/'
only counts files in directory paths containing "/src/" or "/include/".
--not-match-d=REGEXโ counts all files except in directories matching the Perl regex. Only the trailing directory name is compared, for example, when counting in"/usr/local/lib", only"lib"is compared to the regex. Add--fullpathto compare parent directories to the regex. Do not include file path separators at the beginning or end of the regex. This switch may be repeated.--match-f=REGEXโ only counts files whose basenames match the Perl regex. For example this only counts files that start withWidgetorwidget:
--match-f='^[Ww]idget'
Add --fullpath to include parent directories in the regex instead of just the basename.
--not-match-f=REGEXโ counts all files except those whose basenames match the Perl regex. Add--fullpathto include parent directories in the regex instead of just the basename. This switch may be repeated.--skip-archive=REGEXโ ignores files that end with the given Perl regular expression. So if you give it
--skip-archive='(zip|tar(\.(gz|Z|bz2|xz|7z))?)'
the code will skip files that end with .zip, .tar, .tar.gz, .tar.Z, .tar.bz2, .tar.xz, and .tar.7z. Bye ๐
--skip-win-hiddenโ on Windows, ignore hidden files. ๐ซฅ
๐ Debug Options ๐
--categorized=FILEโ saves file sizes in bytes, identified languages and names of categorized files toFILE.--counted=FILEโ saves names of processed source files toFILE. See also--found,--ignored,--unique.--diff-alignment=FILEโ writes toFILEa list of files and file pairs showing which files were added, removed, and/or compared during a run with--diff. This switch forces the--diffmode on.--explain=LANGโ prints the filters used to remove comments for languageLANGand exits. In some cases the filters refer to Perl subroutines rather than regular expressions, so an examination of the source code may be needed for further explanation. iykyk ๐--helpโ prints cloc's internal usage information and exits.--found=FILEโ saves names of every file found toFILE. See also--counted,--ignored,--unique.--ignored=FILEโ saves names of ignored files and the reason they were ignored toFILE. See also--counted,--found,--unique.--print-filter-stagesโ prints toSTDOUTprocessed source code before and after each filter is applied.--show-ext[=EXT]โ prints information about all known (or just the given) file extensions and exits.--show-errors[=EXT]โ used with--quiet, prints error messages (if any).--show-lang[=LANG]โ prints information about all known (or just the given) languages and exits.--show-osโ prints the value of the operating system mode and exits. See also--unix,--windows.--quietโ suppresses all information messages except the final output. See also--shwow-errors. ๐คซ--unique=FILEโ saves names of ignored files and the reason they were ignored toFILE. See also--counted,--found,--ignored.-v[=N]โ turns on verbose with optional numeric value.--verbose[=N]โ long form of-v.--versionโ prints the version of this program and exits.--write-lang-def=FILEโ writes toFILEthe language processing filters then exits. Useful as a first step to creating custom language definitions. Note: languages which map to the same file extension will be excluded. See also--force-lang-def,--read-lang-def.--write-lang-def-incl-dup=FILEโ same as--write-lang-def, but includes duplicated extensions. This generates a problematic language definition file because cloc will refuse to use it until duplicates are removed ๐ฌ
โจ Output Options โจ
--3โ print third-generation language output. heads up bestie ๐ซถ this one can make report summation fail if some of your reports were made with this option and others were made without it. So like... be consistent, ok?--by-percent Xโ instead of showing comment and blank line counts as plain counts, show them as percentages based on whateverXis in the denominator. AndXis one of:cโ meaning lines of codecmโ meaning lines of code + commentscbโ meaning lines of code + blankscmbโ meaning lines of code + comments + blanks
So like, say you use method c and your code has twice as many lines of comments as lines of code? Then the comment column value will be 200%. Wild, right? The code column stays a plain line count tho. ๐
--csvโ write the results as comma separated values. iconic spreadsheet energy ๐--csv-delimiter=Cโ use the characterCas the delimiter for comma separated files instead of,. This switch forces--csvto be on. no take-backsies โจ--file-encoding=Eโ write output files using theEencoding instead of the default ASCII (E='UTF-7'). Examples:'UTF-16','euc-kr','iso-8859-16'. Wanna see the known encodings? Run:
perl -MEncode -e 'print join("\n", Encode->encodings(":all")), "\n"'
--fmt=Nโ alternate text output format whereNis a number from1to5, or-1to-5. 'total lines' means the sum of code, comment, and blank lines. Negative values are the same as the positive values but they retain โ instead of deleting โ the intermediate JSON file that gets written. The JSON file name is randomly generated unless--out/--report-fileis given. The formats are:
1: by language (same as cloc default output)
2: by language with an extra column for total lines
3: by file with language
4: by file with a total lines column
5: by file with language and a total lines column
--hide-rateโ don't show line and file processing rates in the output header. This makes output deterministic. same input, same output, every single time, periodt. โญ--jsonโ write the results in JavaScript Object Notation (JSON). for the girlies who pipe things into other things ๐ฆ--mdโ write the results as Markdown-formatted text.--out=FILEโ synonym for--report-file=FILE. two names, one job ๐--progress-rate=Nโ show a progress update after everyNfiles are processed (defaultN=100). SetNto0to suppress progress output โ super useful when you're redirecting output to STDOUT. ๐ฅ--quietโ suppress all information messages except for the final report. shy girl mode ๐--report-file=FILEโ write the results toFILEinstead of standard output.--summary-cutoff=X:Nโ aggregate to 'Other' the results havingXlines belowN, whereXis one of:cโ meaning lines of codefโ meaning filesmโ meaning lines of commentscmโ meaning lines of code + comments
Appending a percent sign to N changes the calculation from a straight count to a percentage. Ignored with --diff or --by-file. (iykyk)
--sql=FILEโ write results as SQLCREATEandINSERTstatements which can be read by a database program such as SQLite. IfFILEis-, output is sent to STDOUT.--sql-appendโ append SQL insert statements to the file specified by--sqland do not generate the table creation option.--sql-project=NAMEโ usenameas the project identifier for the current run. Only valid with the--sqloption. ๐--sql-style=STYLEโ write SQL statements in the given style instead of the default SQLite format. Styles includeOracleandNamed_Columns.--sum-oneโ for plain text reports, show theSUM:output line even if only one input file is processed. one file still deserves its moment ๐ซถ--xmlโ write the results in XML.--xsl[=FILE]โ referenceFILEas an XSL stylesheet within the XML output. IfFILEis not given, writes a default stylesheet,cloc.xsl. This switch forces--xmlto be on. โจ--yamlโ write the results in YAML.
๐ EXAMPLES ๐
Count the lines of code in the Perl 5.10.0 compressed tar file on a UNIX-like operating system:
cloc perl-5.10.0.tar.gz
Count the changes in files, code, and comments between Python releases 2.6.6 and 2.7:
cloc --diff Python-2.6.6.tar.bz Python-2.7.tar.bz2
Wanna see how cloc aligns files for comparison between two code bases? Use the --diff-alignment=FILE option. Here the alignment information is written to "align.txt":
cloc --diff-alignment=align.txt gcc-4.4.0.tar.bz2 gcc-4.5.0.tar.bz2
Count file, code, and comment changes between two git commits:
cloc --git --diff b409850824 HEAD
Print the recognized languages:
cloc --show-lang
Remove comments from "foo.c" and save the result in "foo.c.nc" ("nc" is an arbitrary extension; used here to denote "no comments"):
cloc --strip-comments=nc foo.c
Additional examples can be found at <https://github.com/AlDanial/cloc>. ๐ฆ
๐ ENVIRONMENT ๐
None. literally nothing here bestie, move along ๐
๐ FILES ๐
None. same vibe, empty page, no notes โจ
โญ SEE ALSO โญ
sloccount(1) โ go say hi to the cousin ๐
๐ AUTHORS ๐
The cloc program was written by Al Danial <al.danial@gmail.com> and is Copyright (C) 2006-2026 <al.danial@gmail.com>.
The manual page was originally written by Jari Aalto <jari.aalto@cante.net>.
Both the code and documentation is released under the GNU GPL version 2 or (at your option) any later version. For more information about license, visit <http://www.gnu.org/copyleft/gpl.html>. ๐ซถ
okay that's the whole page bestie, you ate that ๐
this manual is from cloc version dated 2026-07-20 (that's the source/version and date the page footer carries), filed under section cloc(1) โ go count some lines, you absolute icon ๐ธ๐โจ
๐ฆ where this page comes from
- fedora 43: cloc 2.10-1.fc43 ยท GPL-2.0-or-later
- fedora 44: cloc 2.10-1.fc44 ยท GPL-2.0-or-later
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms