在 bash 中计算(非空白)代码行数

Posted

技术标签:

【中文标题】在 bash 中计算(非空白)代码行数【英文标题】:count (non-blank) lines-of-code in bash 【发布时间】:2010-09-12 00:05:59 【问题描述】:

在 Bash 中,如何计算项目中非空行代码的数量?

【问题讨论】:

下面的很多解决方案只适用于一个文件(例如foo.c)。关于项目中的总行数(例如目录结构中的许多文件,不包括二进制文件)有什么想法吗? @solvingPuzzles 我想我可以回答这部分。对于适用于一个文件的任何解决方案,例如“cat FILE | sed blah”,您可以通过将“cat FILE”替换为列出要操作的文件名的命令来处理许多文件,例如“find .-name '*.py'”,然后将其输入“xargs cat”。例如"查找 .-name '*.py' | xargs cat | sed '/^\s*$/d' | wc -l" @JonathanHartley @solvingPuzzles 还有像 sloccloc 这样的程序可以计算这些代码行数。 OP here:当我第一次问这个问题时,'cloc' 在 Python 代码上做得不是很好。现在很好。 cloc 也可作为 npm 模块使用,节省大量时间。 【参考方案1】:
awk '/^[[:space:]]*$/ ++x END print x' "$testfile"

【讨论】:

我投赞成票只是因为我实际上从未见过有人在 awk 脚本中使用预增量,但不幸的是,这只计算空行。 :) 你的意思是awk '!/^[[:space:]]*$/++x ENDprint x'。或者,如果你真的讨厌负面消息,awk 'y++ /^[[:space:]]*$/++x ENDprint y-x' ;)【参考方案2】:
cat foo.c | sed '/^\s*$/d' | wc -l

如果你考虑 cmets 空行:

cat foo.pl | sed '/^\s*#/d;/^\s*$/d' | wc -l

不过,这取决于语言。

【讨论】:

不确定你为什么在那里使用 cat 。使用 foo.c 或 foo.pl 作为传递给 sed 的文件名。 sed '/^\s*$/d' foo.c | wc -l 只是习惯。我从左到右读取管道,这意味着我通常从 cat 开始,然后是 action、action、action 等。显然,最终结果是相同的。 要对所有子文件夹中的所有文件执行此操作并使用“//”排除 cmets,请将此命令扩展为: find 。 -type f -name '*.c' -exec cat \; | sed '/^\s*#/d;/^\s*$/d;/^\s*\/\//d' | wc -l 没有 UUOC 也可以从左到右阅读:< foo.pl sed 'stuff' | wc -l. 一般来说,UUOC 不重要,可读性才是。【参考方案3】:

'wc' 计算行数、单词数、字符数,因此要计算所有行(包括空白行),请使用:

wc *.py

要过滤掉空行,可以使用grep:

grep -v '^\s*$' *.py | wc

'-v' 告诉 grep 输出除了匹配的行之外的所有行 '^' 是一行的开始 '\s*' 是零个或多个空白字符 '$' 是行尾 *.py 是我希望计算的所有文件的示例(当前目录中的所有 python 文件) 管道输出到 wc。走吧。

我正在回答我自己的(真正的)问题。找不到涵盖此内容的 *** 条目。

【讨论】:

\W 不匹​​配空格,它匹配非单词字符。它与 \w 相反,单词字符。 \W 将匹配任何不是字母数字或下划线的内容,因此不会执行您在此处声明的操作。你的意思是\s【参考方案4】:

如果你想使用非 shell 脚本,试试CLOC:

cloc 计算空行,注释 线和物理源线 许多编程语言的代码。它 完全用 Perl 编写,没有 标准外的依赖 Perl v5.6 及更高版本的分发 (一些外部模块的代码是 嵌入在 cloc 中),所以相当 便携。

【讨论】:

当我第一次问这个问题时,'cloc' 将 Python 文档字符串计为代码行,恕我直言,这是次优的。现代版本的“cloc”现在将 Python 文档字符串视为 cmets,我更喜欢它。 这是正确答案!我刚刚尝试了 cloc,它做得很好。【参考方案5】:

有很多方法可以做到这一点,使用常用的 shell 实用程序。

我的解决办法是:

grep -cve '^\s*$' <file>

这会在 中搜索与模式 (-e) '^\s*$' 匹配的不匹配 (-v) 行,它是行的开头,后跟 0 个或多个空格字符,后跟行尾(即除空格外没有其他内容),并显示匹配行数 (-c) 而不是匹配行本身。

与涉及到wc 的管道方法相比,此方法的一个优点是您可以指定多个文件并为每个文件获取单独的计数:

$ grep -cve '^\s*$' *.hh

config.hh:36
exceptions.hh:48
layer.hh:52
main.hh:39

【讨论】:

谢谢!顺便说一句,wc 确实为每个给定文件提供了计数,加上总数。 不过,如果您正在输入它,则不会,因为标准仅作为一个文件。 这是我认为最好的答案。 -e 不是必需的。那是模式的正常位置,你没有用它做任何时髦的事情。但是如果那是你的风格,那么明确没有错。【参考方案6】:
cat 'filename' | grep '[^ ]' | wc -l

应该做的很好

【讨论】:

当您可以将文件名作为参数传递给 grep 时,为什么要使用 cat 并将文件通过管道传输到 grep 中? 是的,这只是我周围的一个旧别名......它与您的解决方案基本相同,而不是使用逆【参考方案7】:

这有点取决于您在项目中拥有的文件数量。理论上你可以使用

grep -c '.' <list of files>

您可以在哪里使用查找实用程序填写文件列表。

grep -c '.' `find -type f`

会给你每个文件的行数。

【讨论】:

。匹配空格。此解决方案仅在您认为仅包含空格的行是非空白行时才有效,从技术上讲它是非空白行,尽管它可能不是您所追求的。【参考方案8】:
#!/bin/bash
find . -path './pma' -prune -o -path './blog' -prune -o -path './punbb' -prune -o -path './js/3rdparty' -prune -o -print | egrep '\.php|\.as|\.sql|\.css|\.js' | grep -v '\.svn' | xargs cat | sed '/^\s*$/d' | wc -l

上面将为您提供项目(当前文件夹和所有子文件夹递归)的代码行总数(删除空白行)。

在上面的“./blog”、“./punbb”、“./js/3rdparty”和“./pma”是我列入黑名单的文件夹,因为我没有在其中编写代码。 .php、.as、.sql、.css、.js 也是正在查看的文件的扩展名。任何具有不同扩展名的文件都会被忽略。

【讨论】:

Rails 应用程序的变体:find . -path './log' -prune -o -path './trunk' -prune -o -path './branches' -prune -o -path './vendor' -prune -o -path './tmp ' -prune -o -print | egrep '\.rb|\.erb|\.css|\.js|\.yml' | grep -v 'svn' | xargs 猫 | sed '/^\s*$/d' | wc -l 您需要在 grep (...\.js$|...) 中添加 $,否则它将匹配 feature.js.swp 您忘记了锚定,所以它包含错误的文件。还有一个更简单的锚定版本:find . | egrep '.\.c$|.\.h$' | xargs cat | sed '/^\s*$/d' | wc -l【参考方案9】:
grep -v '^\W*$' `find -type f` | grep -c '.' > /path/to/lineCountFile.txt

给出当前目录及其子目录中所有文件的总计数。

HTH!

【讨论】:

\W 是非单词字符;例如,这不会匹配像$-[*] + $@ 这样的行。这肯定是世界上某个地方的有效代码。 ;) 你的意思是 \s 空间。【参考方案10】:

这给出了行数而不计算空白行:

grep -v ^$ filename wc -l | sed -e 's/ //g' 

【讨论】:

【参考方案11】:

用于递归计算当前目录中具有特定文件扩展名的所有非空行的脚本:

#!/usr/bin/env bash
(
echo 0;
for ext in "$@"; do
    for i in $(find . -name "*$ext"); do
        sed '/^\s*$/d' $i | wc -l ## skip blank lines
        #cat $i | wc -l; ## count all lines
        echo +;
    done
done
echo p q;
) | dc;

示例用法:

./countlines.sh .py .java .html

【讨论】:

感谢 @Andy Lester(对您的评论 +1)提供食谱的“非空白”部分。 还要感谢 @Michael Cramer(在您的帖子中 +1)最初发布(稍微冗长的)“非空白”解决方案。【参考方案12】:

如果您想要整个项目中给定文件扩展名的所有文件的所有非空行的总和:

while read line
do grep -cve '^\s*$' "$line"
done <  <(find $1 -name "*.$2" -print) | awk 's+=$1 END print s'

第一个参数是项目的基本目录,第二个是文件扩展名。示例用法:

./scriptname ~/Dropbox/project/src java

它只不过是以前解决方案的集合。

【讨论】:

这个获得了 fork+exec 调用次数最多的奖项,它通过在每个文件中的每行启动一次 grep 来获得。 ;)【参考方案13】:

在 linux 上已经有一个名为“wc”的程序。

只是

wc -l *.c 

它会为您提供总行数和每个文件的行数。

【讨论】:

嘿。 'wc' 本身不会搜索子目录,也不会过滤掉问题中明确要求的空行。 wc 计算空行。 OP想要计算非空行。他确实会想使用wc,但只有在使用sed进行流式编辑后才能使用【参考方案14】:
grep -cvE '(^\s*[/*])|(^\s*$)' foo

-c = count
-v = exclude
-E = extended regex
'(comment lines) OR (empty lines)'
where
^    = beginning of the line
\s   = whitespace
*    = any number of previous characters or none
[/*] = either / or *
|    = OR
$    = end of the line

我发布这个是因为其他选项给了我错误的答案。这适用于我的 java 源代码,其中注释行以 / 或 * 开头(我在多行注释的每一行都使用 *)。

【讨论】:

这是一个可行的解决方案。唯一需要注意的是:它不计算多行 cmets【参考方案15】:

这是一个计算项目中代码行数的 Bash 脚本。它递归地遍历一个源树,它排除了使用“//”的空行和单行cmets。

# $excluded is a regex for paths to exclude from line counting
excluded="spec\|node_modules\|README\|lib\|docs\|csv\|XLS\|json\|png"

countLines()
  # $total is the total lines of code counted
  total=0
  # -mindepth exclues the current directory (".")
  for file in `find . -mindepth 1 -name "*.*" |grep -v "$excluded"`; do
    # First sed: only count lines of code that are not commented with //
    # Second sed: don't count blank lines
    # $numLines is the lines of code
    numLines=`cat $file | sed '/\/\//d' | sed '/^\s*$/d' | wc -l`

    # To exclude only blank lines and count comment lines, uncomment this:
    #numLines=`cat $file | sed '/^\s*$/d' | wc -l`

    total=$(($total + $numLines))
    echo "  " $numLines $file
  done
  echo "  " $total in total


echo Source code files:
countLines
echo Unit tests:
cd spec
countLines

my project 的输出如下所示:

Source code files:
   2 ./buildDocs.sh
   24 ./countLines.sh
   15 ./css/dashboard.css
   53 ./data/un_population/provenance/preprocess.js
   19 ./index.html
   5 ./server/server.js
   2 ./server/startServer.sh
   24 ./SpecRunner.html
   34 ./src/computeLayout.js
   60 ./src/configDiff.js
   18 ./src/dashboardMirror.js
   37 ./src/dashboardScaffold.js
   14 ./src/data.js
   68 ./src/dummyVis.js
   27 ./src/layout.js
   28 ./src/links.js
   5 ./src/main.js
   52 ./src/processActions.js
   86 ./src/timeline.js
   73 ./src/udc.js
   18 ./src/wire.js
   664 in total
Unit tests:
   230 ./ComputeLayoutSpec.js
   134 ./ConfigDiffSpec.js
   134 ./ProcessActionsSpec.js
   84 ./UDCSpec.js
   149 ./WireSpec.js
   731 in total

享受吧! --Curran

【讨论】:

【参考方案16】:

此命令计算非空行的数量。 cat fileName | grep -v ^$ | wc -l grep -v ^$ 正则表达式功能是忽略空行。

【讨论】:

这个答案最直接 这条链中不需要catgrep -v ^$ fileName | wl -l 也不需要wc -l,因为grep有-c:grep -vc ^$ fileName【参考方案17】:
rgrep . | wc -l

给出当前工作目录中非空行的计数。

【讨论】:

【参考方案18】:
cat file.txt | awk 'NF' | wc -l

【讨论】:

喜欢这个简单的??【参考方案19】:

最简洁的命令是

grep -vc ^$ fileName

使用-c 选项,您甚至不需要wc -l

【讨论】:

以上是关于在 bash 中计算(非空白)代码行数的主要内容,如果未能解决你的问题,请参考以下文章

统计python文件中的代码,注释,空白对应的行数

eclipse怎么显示代码行数

eclipse怎么显示代码行数

目录操作习题

如何执行bash脚本时,显示行数

统计代码行数的实用脚本