获取存储库中所有不同文件类型的行数

dig*_*nie 3 git bash

如何获取存储库中所有不同文件类型的行数?例如,如果我的存储库包含3种文件类型:

  • java的
  • XML
  • (没有文件扩展名)

我希望输出是这样的:

java 150
xml 20
(no file extension) 30
Run Code Online (Sandbox Code Playgroud)

我可以运行一个命令来检索特定文件类型的行数(git ls-files | grep "\.java$" | xargs cat | wc -l),但假设我不知道我的存储库中的所有文件类型是什么,我将如何使用它们各自的行数检索它们?

Sto*_*ica 13

这实际上是一个Bash问题:如何计算按文件扩展名分组的文件列表中的行数?

这是一种懒惰的方式awk:

git ls-files | xargs -n100 wc -l | awk -F ' +|\\.' \
    '/\./ { sumlines[$NF] += $2 }
     END { for (ext in sumlines) print ext, sumlines[ext] }'
Run Code Online (Sandbox Code Playgroud)

关键点:

  • git ls-files 为您提供存储库中的文件列表.
  • xargs从其标准输入中获取文件列表并wc -l在其上 运行
    • -n100标志将wc -l在一次调用中传递给最多100个文件.wc -l将被调用多次,因为存储库中的文件数除以100.
  • awk 对每个文件扩展名的行数进行求和和聚合的繁重工作
    • -F ' +|\\.'指定字段分隔符:空格或点.我们的想法是输出wc -l包含以空格开头的行,后跟行数,后跟空格,后跟文件名.通过使用它作为分隔符,第二个字段将是行数,最后一个字段将是文件扩展名.这对计数和聚合很有用.
    • In /\./ { sumlines[$NF] += $2 },$NF是最后一个字段的值,在本例中是文件扩展名,并且$2是行数,如前所述.也就是说,我们将每个扩展的行数相加.该/\./过滤器会排除输入线没有一个..这样做的主要原因是从输出中排除总和的行wc -l.
    • END块打印文件扩展名及其总计数

它是懒惰的,因为它不适用于包含换行符的文件,并且它不计算没有扩展名的文件中的行.


d4R*_*4Rk 5

注意:在重新考虑这一点后,我真的认为 janos 是所问问题的正确答案。因为它确实提供了行数而不是文件数,就像我的解决方案一样。


使用 janos 的解决方案给了我以下错误(我在一个相当大的项目中使用它):

xargs: wc: 参数列表太长

所以我想出了以下解决方案(可能不是最优雅的,但即使在大型项目中也能做到):

git ls-files | awk -F . '{print $NF}' | sort | uniq -c | sort -n -r | awk '{print $2,$1}' | head -10
Run Code Online (Sandbox Code Playgroud)

这基本上包括以下步骤(可以根据您的需要进行修改)

  • 列出 git 已知的所有文件 git ls-files
  • 用于awk获取文件的所有文件类型
  • sort 他们
  • 使它们独一无二并计算出现次数
  • sort 它们颠倒了(出现次数最多的文件类型)
  • 使用awk( $1= count, $2= filetype)打印它们
  • 使用 head