脚本如何实现代码行数统计

wen 实用脚本 1

本文目录导读:

脚本如何实现代码行数统计

  1. Python脚本(最常用)
  2. Shell脚本(Linux/Mac)
  3. Windows Batch脚本
  4. 更完整的Python脚本(支持多种语言)
  5. 一行命令统计(Linux/Mac)
  6. 高级功能(排除特定目录和文件)
  7. 使用建议

Python脚本(最常用)

import os
from pathlib import Path
def count_lines_in_file(filepath):
    """统计单个文件的代码行数"""
    try:
        with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
            lines = f.readlines()
            total = len(lines)
            # 统计有效代码行(去除空行和注释)
            code_lines = 0
            blank_lines = 0
            comment_lines = 0
            for line in lines:
                stripped = line.strip()
                if not stripped:
                    blank_lines += 1
                elif stripped.startswith('#') or stripped.startswith('//'):
                    comment_lines += 1
                else:
                    code_lines += 1
            return total, code_lines, blank_lines, comment_lines
    except:
        return 0, 0, 0, 0
def count_lines_in_directory(directory, extensions=None):
    """统计目录下所有代码文件的行数"""
    if extensions is None:
        extensions = ['.py', '.js', '.java', '.cpp', '.c', '.h', '.html', '.css']
    total_lines = 0
    code_lines = 0
    blank_lines = 0
    comment_lines = 0
    file_count = 0
    for filepath in Path(directory).rglob('*'):
        if filepath.is_file() and filepath.suffix in extensions:
            t, c, b, cm = count_lines_in_file(filepath)
            total_lines += t
            code_lines += c
            blank_lines += b
            comment_lines += cm
            file_count += 1
            print(f"{filepath}: {t} 行 (代码: {c}, 空行: {b}, 注释: {cm})")
    print(f"\n总结:")
    print(f"文件数: {file_count}")
    print(f"总行数: {total_lines}")
    print(f"代码行: {code_lines}")
    print(f"空行: {blank_lines}")
    print(f"注释行: {comment_lines}")
# 使用示例
count_lines_in_directory('.')  # 统计当前目录
# count_lines_in_directory('/path/to/project', ['.py', '.js'])  # 指定目录和文件类型

Shell脚本(Linux/Mac)

#!/bin/bash
# 统计指定目录下所有文件的行数
count_lines() {
    local dir="${1:-.}"
    local extensions="$2"
    echo "统计目录: $dir"
    echo "================================"
    # 按文件类型统计
    if [ -n "$extensions" ]; then
        find "$dir" -type f \( $(echo "$extensions" | sed 's/ / -o -name /g; s/^/-name /') \) -exec wc -l {} + 2>/dev/null
    else
        # 统计所有文件
        find "$dir" -type f -exec wc -l {} + 2>/dev/null
    fi
    # 统计总数
    echo ""
    echo "================================"
    total=$(find "$dir" -type f -exec cat {} + 2>/dev/null | wc -l)
    echo "总计: $total 行"
}
# 统计特定类型文件
count_extensions() {
    local dir="${1:-.}"
    echo "统计Python文件..."
    find "$dir" -name "*.py" -exec wc -l {} + 2>/dev/null
    echo ""
    echo "统计JavaScript文件..."
    find "$dir" -name "*.js" -exec wc -l {} + 2>/dev/null
    echo ""
    echo "统计HTML/CSS文件..."
    find "$dir" \( -name "*.html" -o -name "*.css" \) -exec wc -l {} + 2>/dev/null
}
# 使用示例
# count_lines . "*.py *.js *.java"  # 统计特定类型
# count_extensions .                # 统计常见类型

Windows Batch脚本

@echo off
setlocal enabledelayedexpansion
:: 统计代码行数
set "target_dir=."
set total=0
set file_count=0
echo 统计目录: %target_dir%
echo ================================
:: 统计特定文件类型
for /r "%target_dir%" %%f in (*.py *.js *.java *.cpp *.c *.h) do (
    if exist "%%f" (
        set /a file_count+=1
        for /f %%a in ('type "%%f" ^| find /c /v ""') do (
            set lines=%%a
            set /a total+=lines
            echo %%f: !lines! 行
        )
    )
)
echo ================================
echo 文件数: %file_count%
echo 总行数: %total%
pause

更完整的Python脚本(支持多种语言)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import re
from collections import defaultdict
class CodeLineCounter:
    def __init__(self):
        # 不同语言的注释符号
        self.comment_patterns = {
            '.py': [r'^\s*#', r'^\s*""".*?"""'],
            '.js': [r'^\s*//', r'^\s*/\*.*?\*/'],
            '.java': [r'^\s*//', r'^\s*/\*.*?\*/'],
            '.c': [r'^\s*//', r'^\s*/\*.*?\*/'],
            '.cpp': [r'^\s*//', r'^\s*/\*.*?\*/'],
            '.h': [r'^\s*//', r'^\s*/\*.*?\*/'],
            '.html': [r'^\s*<!--.*?-->'],
            '.css': [r'^\s*/\*.*?\*/'],
        }
    def is_comment(self, line, ext):
        """判断是否为注释行"""
        if ext not in self.comment_patterns:
            return False
        stripped = line.strip()
        for pattern in self.comment_patterns[ext]:
            if re.match(pattern, stripped):
                return True
        return False
    def count_file(self, filepath):
        """统计单个文件"""
        ext = os.path.splitext(filepath)[1].lower()
        try:
            with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
                content = f.read()
        except:
            return None
        lines = content.splitlines()
        total = len(lines)
        code = 0
        blank = 0
        comments = 0
        for line in lines:
            if not line.strip():
                blank += 1
            elif self.is_comment(line, ext):
                comments += 1
            else:
                code += 1
        return {
            'file': filepath,
            'extension': ext,
            'total': total,
            'code': code,
            'blank': blank,
            'comments': comments
        }
    def count_directory(self, directory, extensions=None):
        """统计目录"""
        if extensions is None:
            extensions = ['.py', '.js', '.java', '.cpp', '.c', '.h', 
                         '.html', '.css', '.php', '.rb', '.go', '.rs']
        results = []
        totals = defaultdict(int)
        for root, dirs, files in os.walk(directory):
            # 跳过隐藏目录和node_modules等
            dirs[:] = [d for d in dirs if not d.startswith('.') 
                      and d not in ['node_modules', 'venv', 'env', '__pycache__']]
            for file in files:
                ext = os.path.splitext(file)[1].lower()
                if ext in extensions:
                    filepath = os.path.join(root, file)
                    result = self.count_file(filepath)
                    if result:
                        results.append(result)
                        totals['files'] += 1
                        totals['total'] += result['total']
                        totals['code'] += result['code']
                        totals['blank'] += result['blank']
                        totals['comments'] += result['comments']
        return results, totals
def main():
    import argparse
    parser = argparse.ArgumentParser(description='代码行数统计工具')
    parser.add_argument('path', help='要统计的文件或目录路径')
    parser.add_argument('-e', '--extensions', nargs='+', 
                       help='要统计的文件扩展名,.py .js')
    parser.add_argument('-v', '--verbose', action='store_true',
                       help='显示详细统计信息')
    args = parser.parse_args()
    counter = CodeLineCounter()
    if os.path.isfile(args.path):
        result = counter.count_file(args.path)
        if result:
            print(f"文件: {result['file']}")
            print(f"总行数: {result['total']}")
            print(f"代码行: {result['code']}")
            print(f"空行: {result['blank']}")
            print(f"注释行: {result['comments']}")
    else:
        results, totals = counter.count_directory(args.path, args.extensions)
        print(f"\n统计目录: {args.path}")
        print("=" * 50)
        if args.verbose:
            for result in results:
                print(f"{result['file']}: {result['total']}行 "
                      f"(代码: {result['code']}, "
                      f"空行: {result['blank']}, "
                      f"注释: {result['comments']})")
        print(f"\n总计:")
        print(f"文件数: {totals['files']}")
        print(f"总行数: {totals['total']}")
        print(f"代码行: {totals['code']}")
        print(f"空行: {totals['blank']}")
        print(f"注释行: {totals['comments']}")
        print(f"代码占比: {totals['code']/totals['total']*100:.1f}%")
if __name__ == '__main__':
    main()

一行命令统计(Linux/Mac)

# 统计Python文件
find . -name "*.py" -type f -exec wc -l {} + | tail -1
# 统计所有代码文件
find . \( -name "*.py" -o -name "*.js" -o -name "*.java" \) -type f -exec cat {} + | wc -l
# 统计并排除node_modules和venv
find . -type f \( -name "*.py" -o -name "*.js" \) \
  -not -path "./node_modules/*" \
  -not -path "./venv/*" \
  -exec wc -l {} + | sort -n
# 使用cloc工具(需安装)
cloc . --exclude-dir=node_modules,venv

高级功能(排除特定目录和文件)

import fnmatch
def should_ignore(filepath, ignore_patterns):
    """检查是否应该忽略该文件"""
    for pattern in ignore_patterns:
        if fnmatch.fnmatch(filepath, pattern):
            return True
    return False
# 使用示例
ignore_patterns = [
    '*/node_modules/*',
    '*/venv/*',
    '*/__pycache__/*',
    '*.min.js',      # 压缩文件
    '*.min.css',     # 压缩文件
    '*generated*',   # 生成的文件
]

使用建议

  1. 简单场景:使用Shell一行命令
  2. 项目统计:使用完整的Python脚本
  3. Git仓库:可以使用 git ls-files | xargs wc -l
  4. 专业工具:使用 cloctokeiscc 等工具

这些脚本可以帮助你快速统计代码行数,根据需要选择合适的版本。

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