计算所有.c和.h文件中的行数

时间:2017-11-05 19:25:01

标签: bash shell

我正在尝试编写一个shell脚本,它将计算格式为.c.h的目录(及其子目录)中每个文件中所有行的总和。

我已经拥有该代码,但我不确定如何找到这两种文件格式。

!/bin/bash
#Program
total=0
find /path -type f -name "*.php" | while read FILE; do
     count=$(grep -c ^ < "$FILE")
     echo "$FILE has $count lines"
     let total=total+count 
done
echo TOTAL LINES COUNTED:  $total

我是shell / bash的新手,如果有任何其他错误,我将不胜感激。

4 个答案:

答案 0 :(得分:4)

优化 find + GNU parallel 解决方案:

find /path -type f -name "*.[ch]" -print0 | parallel -q0 -j0 --no-notice  wc -l {} \
| awk '{ sum+=$1 }END{ print "TOTAL LINES COUNTED: "sum }'
  • -print0 - 在标准输出上打印完整文件名,后跟空字符(而不是-print使用的换行符)。这允许处理 find 输出的程序正确解释包含换行符或其他类型的空格的文件名。
  • 使用parallel命令wc -l {}将针对每个文件并行(这称为并行处理)

答案 1 :(得分:2)

要查找.c.h个文件而不是.php, 只需将-name参数的值更改为*.[ch]

脚本中还有一些其他问题:

  • 将文件名读作IFS= read -r
  • 会更安全
  • 第一行应为#!/bin/bash,而不是!/bin/bash

可能会有一些小的改进:

  • 使用((...))语法(算术上下文)
  • 可以更简单地编写求和逻辑
  • 不建议使用大写变量名,因为该转换保留给系统变量

把它放在一起:

#!/bin/bash

total=0
find /path -type f -name "*.[ch]" | while IFS= read -r file; do
     count=$(grep -c ^ < "$file")
     echo "$file has $count lines"
     ((total += count))
done
echo TOTAL LINES COUNTED:  $total

其他答案推荐find ... -exec wc -l的变体。 虽然看起来更优雅, 它们的工作方式与脚本完全不同:

  • wc -l计算的行数与grep -c ^略有不同。特别是它不计算文件的最后一行,如果它不以换行符结束。试试例如printf hello > file; wc -l file; grep -c ^ file - &gt;你会得到0和1。
  • 获取单个文件中的行数,总行数不是那么简单。使用find ... -exec wc -l {} +非常接近(如果find的实施支持+),但同样会出现需要特殊处理的极端情况。例如,如果文件太多,则会多次调用wc,从而生成需要协调的多个子总计。

答案 2 :(得分:1)

试试这个:

cat $(find /path -type f \( -name '*.c' -o -name '*.h' \)) |wc -l

它会在cat返回的每个文件上运行find,并将输出传递到wc。如果您需要变量中的值,请执行此操作

lines=$(cat ...)
echo counted $lines lines

答案 3 :(得分:1)

将所有文件以.c.h结尾并输入grep -c

find -type f -name '*.[ch]' -exec cat {} + | grep -c '^'

对于没有+选项的查找,替代方法是

find -type f -name '*.[ch]' -exec cat {} \; | grep -c '^'

每个文件调用一次cat而不是尽可能少的几次,使其慢一点。

如果您知道不会有很多文件接近命令行长度限制,那么您可以使用shell globbing:

shopt -s globstar # enable **/* glob
cat **/*.[ch] | grep -c '^'