本文目录导读:

- Python脚本(最常用)
- Shell脚本(Linux/Mac)
- Windows Batch脚本
- 更完整的Python脚本(支持多种语言)
- 一行命令统计(Linux/Mac)
- 高级功能(排除特定目录和文件)
- 使用建议
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*', # 生成的文件
]
使用建议
- 简单场景:使用Shell一行命令
- 项目统计:使用完整的Python脚本
- Git仓库:可以使用
git ls-files | xargs wc -l - 专业工具:使用
cloc、tokei或scc等工具
这些脚本可以帮助你快速统计代码行数,根据需要选择合适的版本。