本文目录导读:

Python 脚本(通用性强,推荐)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量生成文件索引脚本
功能:扫描指定目录,生成文件索引(CSV/JSON/Markdown格式)
"""
import os
import csv
import json
import argparse
from datetime import datetime
from pathlib import Path
class FileIndexer:
def __init__(self, root_dir, output_format='csv', include_hidden=False):
self.root_dir = Path(root_dir).resolve()
self.output_format = output_format.lower()
self.include_hidden = include_hidden
self.files = []
def scan_directory(self):
"""扫描目录收集文件信息"""
self.files = []
for root, dirs, files in os.walk(self.root_dir):
# 可选:跳过隐藏文件夹
if not self.include_hidden:
dirs[:] = [d for d in dirs if not d.startswith('.')]
files = [f for f in files if not f.startswith('.')]
for file in files:
file_path = Path(root) / file
try:
stat = file_path.stat()
self.files.append({
'name': file,
'path': str(file_path.relative_to(self.root_dir)),
'full_path': str(file_path),
'size': stat.st_size,
'modified': datetime.fromtimestamp(stat.st_mtime).isoformat(),
'created': datetime.fromtimestamp(stat.st_ctime).isoformat(),
'extension': file_path.suffix.lower()
})
except (OSError, PermissionError):
continue
return self.files
def export_csv(self, output_file):
"""导出为CSV格式"""
if not self.files:
print("没有找到文件")
return False
try:
with open(output_file, 'w', newline='', encoding='utf-8-sig') as f:
fieldnames = ['name', 'path', 'size', 'modified', 'created', 'extension']
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(self.files)
print(f"CSV索引已保存: {output_file}")
return True
except Exception as e:
print(f"导出CSV失败: {e}")
return False
def export_json(self, output_file):
"""导出为JSON格式"""
if not self.files:
print("没有找到文件")
return False
output = {
'root_directory': str(self.root_dir),
'total_files': len(self.files),
'generated_at': datetime.now().isoformat(),
'files': self.files
}
try:
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(output, f, ensure_ascii=False, indent=2)
print(f"JSON索引已保存: {output_file}")
return True
except Exception as e:
print(f"导出JSON失败: {e}")
return False
def export_markdown(self, output_file):
"""导出为Markdown格式(带目录树)"""
if not self.files:
print("没有找到文件")
return False
try:
with open(output_file, 'w', encoding='utf-8') as f:
f.write(f"# 文件索引\n\n")
f.write(f"- **根目录**: {self.root_dir}\n")
f.write(f"- **文件总数**: {len(self.files)}\n")
f.write(f"- **生成时间**: {datetime.now().isoformat()}\n\n")
# 按扩展名分组
from collections import defaultdict
grouped = defaultdict(list)
for file in self.files:
ext = file['extension'] or '(无扩展名)'
grouped[ext].append(file)
for ext, files in sorted(grouped.items()):
f.write(f"## {ext.upper()} ({len(files)}个文件)\n\n")
f.write("| 文件名 | 路径 | 大小 | 修改时间 |\n")
f.write("|--------|------|------|----------|\n")
# 文件列表,按大小排序(大到小)
for file in sorted(files, key=lambda x: x['size'], reverse=True):
size_mb = file['size'] / (1024*1024)
f.write(f"| {file['name']} | {file['path']} | {size_mb:.2f} MB | {file['modified'][:10]} |\n")
f.write("\n")
print(f"Markdown索引已保存: {output_file}")
return True
except Exception as e:
print(f"导出Markdown失败: {e}")
return False
def export(self, output_file):
"""根据格式自动导出"""
if self.output_format == 'csv':
return self.export_csv(output_file)
elif self.output_format == 'json':
return self.export_json(output_file)
elif self.output_format == 'md':
return self.export_markdown(output_file)
else:
# 根据文件扩展名判断
if output_file.endswith('.csv'):
return self.export_csv(output_file)
elif output_file.endswith('.json'):
return self.export_json(output_file)
elif output_file.endswith('.md'):
return self.export_markdown(output_file)
else:
print(f"不支持的输出格式: {self.output_format}")
return False
def main():
parser = argparse.ArgumentParser(description='批量生成文件索引')
parser.add_argument('directory', help='要扫描的目录路径')
parser.add_argument('-o', '--output', default='file_index.csv',
help='输出文件路径 (默认: file_index.csv)')
parser.add_argument('-f', '--format', choices=['csv', 'json', 'md'],
default='csv', help='输出格式 (默认: csv)')
parser.add_argument('--hidden', action='store_true',
help='包含隐藏文件')
parser.add_argument('--extensions', nargs='+',
help='只索引指定扩展名,如 --extensions .py .txt')
args = parser.parse_args()
indexer = FileIndexer(args.directory, args.format, args.hidden)
files = indexer.scan_directory()
# 如果指定了扩展名过滤
if args.extensions:
indexer.files = [f for f in files if f['extension'] in args.extensions]
print(f"过滤后: {len(indexer.files)}个文件")
if not indexer.files:
print("警告: 没有找到匹配的文件")
return
indexer.export(args.output)
# 打印统计信息
total_size = sum(f['size'] for f in indexer.files)
print(f"\n=== 统计信息 ===")
print(f"总文件数: {len(indexer.files)}")
print(f"总大小: {total_size / (1024*1024):.2f} MB")
print(f"最大文件: {max(indexer.files, key=lambda x: x['size'])['name']}")
if __name__ == '__main__':
main()
使用方法:
# 基本使用:扫描当前目录,生成CSV索引 python file_indexer.py /path/to/directory # 指定输出格式为JSON python file_indexer.py /path/to/directory -f json -o index.json # 只索引Python和文本文件 python file_indexer.py /path/to/directory --extensions .py .txt # 包含隐藏文件 python file_indexer.py /path/to/directory --hidden
Bash 脚本(Linux/Mac)
#!/bin/bash
# 批量生成文件索引脚本(Bash版)
# 配置
ROOT_DIR="${1:-.}" # 目标目录,默认当前目录
OUTPUT_FILE="${2:-file_index.txt}" # 输出文件
INCLUDE_HIDDEN=false # 是否包含隐藏文件
MAX_DEPTH="" # 最大深度,留空为无限
# 显示用法
usage() {
echo "用法: $0 [目录路径] [输出文件]"
echo " -h, --help 显示帮助"
echo " -a, --all 包含隐藏文件"
echo " -d, --depth 设置最大扫描深度"
echo " -s, --size 按大小排序"
echo " -t, --time 按修改时间排序"
exit 1
}
# 解析参数
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help) usage ;;
-a|--all) INCLUDE_HIDDEN=true; shift ;;
-d|--depth) MAX_DEPTH="$2"; shift 2 ;;
-s|--size) SORT_BY_SIZE=true; shift ;;
-t|--time) SORT_BY_TIME=true; shift ;;
*) ROOT_DIR="$1"; shift ;;
esac
done
# 验证目录
if [ ! -d "$ROOT_DIR" ]; then
echo "错误: 目录 '$ROOT_DIR' 不存在"
exit 1
fi
# 构建find命令
CMD="find \"$ROOT_DIR\""
[ -n "$MAX_DEPTH" ] && CMD+=" -maxdepth $MAX_DEPTH"
[ "$INCLUDE_HIDDEN" = false ] && CMD+=" -not -path '*/.*'"
CMD+=" -type f"
# 添加排序
if [ "$SORT_BY_SIZE" = true ]; then
CMD+=" -exec ls -lhS {} +"
elif [ "$SORT_BY_TIME" = true ]; then
CMD+=" -exec ls -lht {} +"
else
CMD+=" -exec ls -lh {} +"
fi
# 执行并保存
echo "正在扫描目录: $ROOT_DIR"
echo "生成索引文件: $OUTPUT_FILE"
# 写入文件头
{
echo "=========================================="
echo "文件索引 - 生成时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "根目录: $(realpath "$ROOT_DIR")"
echo "=========================================="
echo ""
# 执行find命令
eval "$CMD" | sort -k8,8
echo ""
echo "=========================================="
echo "统计信息"
echo "总文件数: $(eval "find \"$ROOT_DIR\" -type f $( [ \"$INCLUDE_HIDDEN\" = false ] && echo '-not -path \"*/.*\"' ) | wc -l")"
echo "总大小: $(eval "du -sh \"$ROOT_DIR\" $( [ \"$INCLUDE_HIDDEN\" = false ] && echo '--exclude=\"*/.*\"' ) 2>/dev/null | cut -f1")"
echo "=========================================="
} > "$OUTPUT_FILE"
echo "完成!索引已保存到: $OUTPUT_FILE"
Windows PowerShell 脚本
# 批量生成文件索引脚本(PowerShell版)
param(
[Parameter(Mandatory=$false)]
[string]$Path = ".",
[Parameter(Mandatory=$false)]
[string]$OutputFile = "file_index.csv",
[Parameter(Mandatory=$false)]
[switch]$IncludeHidden,
[Parameter(Mandatory=$false)]
[string[]]$Extensions,
[Parameter(Mandatory=$false)]
[switch]$ExportToExcel
)
# 函数:获取文件信息
function Get-FileInfo {
param($File)
$info = [PSCustomObject]@{
Name = $File.Name
FullName = $File.FullName
RelativePath = $File.FullName.Replace((Get-Item $Path).FullName, "").TrimStart("\")
Extension = $File.Extension
Size = $File.Length
SizeMB = [math]::Round($File.Length / 1MB, 2)
LastModified = $File.LastWriteTime
Created = $File.CreationTime
IsHidden = $File.Attributes -band [System.IO.FileAttributes]::Hidden
Attributes = $File.Attributes.ToString()
}
return $info
}
# 主逻辑
try {
Write-Host "正在扫描目录: $Path" -ForegroundColor Cyan
# 获取文件
if ($IncludeHidden) {
$files = Get-ChildItem -Path $Path -Recurse -File -Force
} else {
$files = Get-ChildItem -Path $Path -Recurse -File
}
# 过滤扩展名
if ($Extensions) {
$files = $files | Where-Object { $_.Extension -in $Extensions }
}
# 获取文件信息
$fileInfos = $files | ForEach-Object { Get-FileInfo $_ }
# 统计信息
$totalFiles = $fileInfos.Count
$totalSize = ($fileInfos | Measure-Object -Property Size -Sum).Sum
# 导出CSV
$fileInfos | Export-Csv -Path $OutputFile -NoTypeInformation -Encoding UTF8
Write-Host "CSV索引已保存: $OutputFile" -ForegroundColor Green
# 可选:导出为Excel(需要安装Excel)
if ($ExportToExcel) {
$excelFile = $OutputFile -replace '\.csv$', '.xlsx'
$fileInfos | Export-Excel -Path $excelFile -AutoSize -TableStyle Medium6
Write-Host "Excel索引已保存: $excelFile" -ForegroundColor Green
}
# 打印统计
Write-Host ""
Write-Host "=== 统计信息 ===" -ForegroundColor Yellow
Write-Host "总文件数: $totalFiles"
Write-Host "总大小: $([math]::Round($totalSize / 1MB, 2)) MB"
# 显示前10大文件
Write-Host ""
Write-Host "前10大文件:" -ForegroundColor Yellow
$fileInfos | Sort-Object -Property Size -Descending |
Select-Object -First 10 |
Format-Table Name, SizeMB, LastModified -AutoSize
} catch {
Write-Host "错误: $_" -ForegroundColor Red
exit 1
}
推荐使用场景
| 场景 | 推荐脚本 | 说明 |
|---|---|---|
| 跨平台使用 | Python脚本 | 功能最全面,适合正式使用 |
| Linux/Mac快速索引 | Bash脚本 | 不需要安装Python,简单快速 |
| Windows系统 | PowerShell脚本 | 原生支持,可导出Excel |
安装依赖(Python脚本)
# Python脚本无需额外依赖(标准库) # 如需Excel导出功能,可安装 pip install openpyxl pandas
选择适合你需求的脚本,如有特殊要求可以告诉我,我可以帮你定制修改!