本文目录导读:

- 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等工具
这些脚本可以帮助你快速统计代码行数,根据需要选择合适的版本。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播