如何计算程序文件中的行数(多个),过滤一些文件和一些行?

时间:2016-02-06 18:52:01

标签: linux bash

我有一堆我用find命令选择的代码文件。

我需要计算代码行,但过滤掉我不关心的行 - 即所有import语句。

我怎样才能在bash中执行此操作?

这是我到目前为止所拥有的:

function codecount { find . -name "$@" | grep -v test | xargs wc -l; }

因此,如果我运行codecount *.java,它将找到我的所有Java文件,消除任何测试代码,然后计算行数。我想进一步细化这个过滤掉" import"行数之前的剩余文件上的行。

3 个答案:

答案 0 :(得分:1)

在Bash中,您可以将.pipe(htmlmin({ removeEmptyAttributes: true, customAttrAssign: [{"source":"\\$="}], customAttrSurround: [ [ {"source": "\\({\\{"}, {"source": "\\}\\}"} ], [ {"source": "\\[\\["}, {"source": "\\]\\]"} ] ], collapseWhitespace: true, // always leave one space // because http://perfectionkills.com/experimenting-with-html-minifier/#collapse_whitespace conservativeCollapse: true, minifyJS: true, minifyCSS: true, removeComments: true, removeCommentsFromCDATA: true, removeCDATASectionsFromCDATA: true })) globstar一起使用:

extglob

阐释:

  • shopt -s extglob shopt -s globstar codecount() { grep -v ^import **/!(test*).java | wc -l } 打印grep -v ^import <file-list>以外的所有行,但以<file-list>开头的行除外。
  • import可以分解为三个部分:

    • **/!(test*).java用于匹配当前目录和子目录中的所有文件;
    • **表示:除!(test*);
    • 开头的文件外的所有内容
    • test:以.java
    • 结尾的所有内容

    因此,最终它将匹配除.java开头的所有Java文件。

  • test计算行数。

请注意,它也会计算空行。如果要排除空行,​​请使用:

wc -l

答案 1 :(得分:1)

我建议您考虑使用ag代替grep

它是为这种用法而创建的,它比grep更快,因为它会自动忽略二进制文件和.git文件夹等。它还有许多有用的额外选项。

列出包含导入的文件路径以及每个文件中匹配的行数

ag import --java --count

详细摘要

ag import --java --stats

您当然也可以通过正则表达式进行搜索。我认为这将给出您正在寻找的结果,通过使用反转匹配仅显示不匹配的行,并且nogroup不为每个文件添加间隙和标题。

ag '(^import|test)' --invert-match --java --nogroup | wc -l

答案 2 :(得分:1)

几乎只能使用grep:

grep -r --include='*.java' --exclude='*test*' -vch '^import' *

执行以下操作:

  • -r:递归搜索所有子目录
  • --include='*.java':只有以.java
  • 结尾的grep文件
  • --exclude-'*test*':...但排除名称中包含test
  • 的文件
  • -v '^import':反转匹配,排除以import
  • 开头的行
  • -c:计算匹配而不是返回它们(每行计数)
  • -h:禁止输出文件名,只打印匹配数

返回类似

的内容
2
3
5

我们只想要总数。我们可以退后一步,打印匹配的行,然后用| paste -s -d '+' | bc计算它们,而不是管道| awk '{sum += $1} END { print sum }'甚至wc

grep -r --include='*.java' --exclude='*test*' -vh '^import' * | wc -l

这可以变成一个函数,其中参数决定了应该包含的内容,我们只需要小心引用:

codecount () {
    grep -r --include="$1" --exclude='*test*' -vh '^import' * | wc -l
}

这必须像

一样调用
codecount '*.java'

以避免在函数中使用之前扩展*

OP解决方案的最小变化:

如果你真的想使用findgrepxargs,你可以像这样修改你的尝试:

codecount () {
    find . -name "$@" | grep -v test | xargs grep -v '^import' | wc -l
}

我刚刚添加了一个grep -v步骤来过滤以import开头的行(并将function codecount替换为codecount ()以提高可移植性。)

请注意,需要在命令行上使用引号调用此仍然

codecount '*.java'

find -exec catgrep

最后一个解决方案:使用find过滤包含test而不是xargs grep -v的文件名,然后cat,以便grep看不到文件名:< / p>

find -type f -name '*.java' -not -name '*test*' -exec cat {} \; |
grep -vc '^import'

这可以像其他两个例子一样成为一个函数,引用的注释仍然适用。