如何写一个脚本统计代码行数

wen 实用脚本 1

本文目录导读:

如何写一个脚本统计代码行数

  1. 基础版:纯Shell脚本
  2. 进阶版:带详细分类统计
  3. Python版(功能更强大)
  4. 使用示例
  5. 更轻量的单行命令
  6. 使用方法

我来教你写一个统计代码行数的脚本,包含多种实现方式。

基础版:纯Shell脚本

#!/bin/bash
# 统计代码行数 - 基础版
# 目标目录,默认为当前目录
TARGET_DIR="${1:-.}"
# 统计代码行数
find "$TARGET_DIR" -type f \( -name "*.py" -o -name "*.java" -o -name "*.js" -o -name "*.cpp" -o -name "*.c" -o -name "*.go" \) | xargs wc -l | tail -1

进阶版:带详细分类统计

#!/bin/bash
# 统计代码行数 - 进阶版
TARGET_DIR="${1:-.}"
# 定义常见的代码文件扩展名
CODE_EXTENSIONS=("py" "java" "js" "ts" "cpp" "c" "h" "go" "rb" "php" "sh" "html" "css" "sql")
echo "代码行数统计报告"
echo "=================="
echo
total_lines=0
total_files=0
# 遍历每个扩展名
for ext in "${CODE_EXTENSIONS[@]}"; do
    files=$(find "$TARGET_DIR" -type f -name "*.$ext" 2>/dev/null)
    count_files=$(echo "$files" | wc -l)
    if [ "$files" != "" ]; then
        lines=$(echo "$files" | xargs cat | wc -l)
        echo "$ext 文件: $count_files 个, 总行数: $lines"
        total_lines=$((total_lines + lines))
        total_files=$((total_files + count_files))
    fi
done
echo "=================="
echo "总计: $total_files 个文件, $total_lines 行代码"

Python版(功能更强大)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""统计代码行数脚本"""
import os
import sys
from pathlib import Path
from collections import defaultdict
class CodeLineCounter:
    def __init__(self, root_dir='.', extensions=None, skip_blank=True, skip_comments=True):
        self.root_dir = Path(root_dir)
        self.extensions = extensions or [
            '.py', '.java', '.js', '.ts', '.cpp', '.c', '.h',
            '.go', '.rb', '.php', '.sh', '.html', '.css', '.sql'
        ]
        self.skip_blank = skip_blank
        self.skip_comments = skip_comments
        self.stats = defaultdict(lambda: {'files': 0, 'lines': 0})
        self.total_files = 0
        self.total_lines = 0
    def is_comment_line(self, line, file_ext):
        """判断是否为注释行"""
        line = line.strip()
        if not line:
            return False
        # 根据文件类型判断注释
        if file_ext in ['.py', '.rb', '.sh']:
            return line.startswith('#')
        elif file_ext in ['.java', '.js', '.ts', '.cpp', '.c', '.h', '.go', '.php']:
            return line.startswith('//') or line.startswith('*') or line.startswith('/*')
        elif file_ext in ['.html', '.css']:
            return line.startswith('<!--') or line.startswith('/*')
        return False
    def count_file_lines(self, filepath):
        """统计单个文件的有效代码行数"""
        filepath = Path(filepath)
        lines_count = 0
        is_block_comment = False
        try:
            with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
                for line in f:
                    line_stripped = line.strip()
                    # 检查块注释
                    if '/*' in line_stripped:
                        is_block_comment = True
                        continue
                    if '*/' in line_stripped:
                        is_block_comment = False
                        continue
                    # 跳过空行
                    if self.skip_blank and not line_stripped:
                        continue
                    # 跳过注释行
                    if self.skip_comments and self.is_comment_line(line_stripped, filepath.suffix):
                        continue
                    # 跳过块注释中的内容
                    if is_block_comment:
                        continue
                    lines_count += 1
        except Exception as e:
            print(f"Error reading {filepath}: {e}")
        return lines_count
    def count(self):
        """统计所有文件"""
        for root, dirs, files in os.walk(self.root_dir):
            # 跳过常见的无用目录
            dirs[:] = [d for d in dirs if d not in [
                '.git', 'node_modules', 'venv', '__pycache__', 
                'build', 'dist', '.idea', '.vscode'
            ]]
            for file in files:
                filepath = Path(root) / file
                if filepath.suffix in self.extensions:
                    lines = self.count_file_lines(filepath)
                    ext = filepath.suffix
                    self.stats[ext]['files'] += 1
                    self.stats[ext]['lines'] += lines
                    self.total_files += 1
                    self.total_lines += lines
        return self.total_lines
    def print_report(self):
        """打印统计报告"""
        print(f"\n{'='*60}")
        print(f"代码行数统计报告")
        print(f"{'='*60}")
        print(f"统计目录: {self.root_dir}")
        print(f"文件总数: {self.total_files}")
        print(f"总行数: {self.total_lines}")
        print(f"\n按文件类型分类:")
        print(f"{'文件类型':<12} {'文件数':<10} {'代码行数':<10} {'平均行数':<10}")
        print(f"{'-'*42}")
        for ext, data in sorted(self.stats.items(), key=lambda x: x[1]['lines'], reverse=True):
            avg = data['lines'] // data['files'] if data['files'] > 0 else 0
            print(f"{ext:<12} {data['files']:<10} {data['lines']:<10} {avg:<10}")
        print(f"{'='*60}")
def main():
    # 命令行参数
    target_dir = sys.argv[1] if len(sys.argv) > 1 else '.'
    skip_blank = '--keep-blank' not in sys.argv
    skip_comments = '--keep-comments' not in sys.argv
    # 创建计数器并统计
    counter = CodeLineCounter(
        root_dir=target_dir,
        skip_blank=skip_blank,
        skip_comments=skip_comments
    )
    counter.count()
    counter.print_report()
if __name__ == '__main__':
    main()

使用示例

运行Shell版:

# 统计当前目录
./code_counter.sh
# 统计指定目录
./code_counter.sh /path/to/project

运行Python版:

# 基本用法
python3 code_counter.py
# 指定目录
python3 code_counter.py /path/to/project
# 保留空行统计
python3 code_counter.py --keep-blank
# 保留注释行
python3 code_counter.py --keep-comments

更轻量的单行命令

如果你只需要快速统计,可以直接用命令:

# 统计所有Python文件行数
find . -name "*.py" | xargs wc -l
# 统计所有代码文件(排除node_modules等)
find . -type f \( -name "*.py" -o -name "*.js" -o -name "*.java" \) \
    ! -path "./node_modules/*" ! -path "./.git/*" | xargs wc -l
# 使用cloc工具(需要安装)
cloc . --exclude-dir=node_modules

使用方法

  1. 保存脚本:将上述脚本保存为 code_counter.shcode_counter.py
  2. 添加执行权限
    chmod +x code_counter.sh
  3. 运行脚本
    ./code_counter.sh [目录路径]

选择建议:

  • 快速统计:使用Shell脚本
  • 需要详细报告:使用Python脚本
  • 大型项目:建议安装并使用cloc工具

这个脚本可以很好地统计代码行数,并自动排除空行和注释行。

抱歉,评论功能暂时关闭!