我有一堆我用find
命令选择的代码文件。
我需要计算代码行,但过滤掉我不关心的行 - 即所有import
语句。
我怎样才能在bash中执行此操作?
这是我到目前为止所拥有的:
function codecount { find . -name "$@" | grep -v test | xargs wc -l; }
因此,如果我运行codecount *.java
,它将找到我的所有Java文件,消除任何测试代码,然后计算行数。我想进一步细化这个过滤掉" import"行数之前的剩余文件上的行。
答案 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
--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解决方案的最小变化:
如果你真的想使用find
,grep
和xargs
,你可以像这样修改你的尝试:
codecount () {
find . -name "$@" | grep -v test | xargs grep -v '^import' | wc -l
}
我刚刚添加了一个grep -v
步骤来过滤以import
开头的行(并将function codecount
替换为codecount ()
以提高可移植性。)
请注意,需要在命令行上使用引号调用此仍然:
codecount '*.java'
find -exec cat
和grep
:
最后一个解决方案:使用find
过滤包含test
而不是xargs grep -v
的文件名,然后cat
,以便grep看不到文件名:< / p>
find -type f -name '*.java' -not -name '*test*' -exec cat {} \; |
grep -vc '^import'
这可以像其他两个例子一样成为一个函数,引用的注释仍然适用。