🎯 学习目标:学会代码管理和项目组织
⏱️ 阅读时间:约 10 分钟
💡 前置要求:无
📁 文件操作能做什么?
支持的操作总览
| 读取 | ||
| 写入 | ||
| 编辑 | ||
| 管理 | ||
| 分析 |
🚀 基础操作
读取文件
使用方式
# 读取文件内容"读取 ~/projects/app/src/main.py 的内容"# 读取特定行"读取 config.json 的第 10 到 20 行"# 搜索内容"在项目中搜索'TODO'标记"技能实现
module.exports = {name: 'read-file',asyncexecute({ filePath, startLine, endLine }) {try {const content = awaitreadFile(filePath);if (startLine && endLine) {const lines = content.split('\n');return lines.slice(startLine - 1, endLine).join('\n'); }return content; } catch (error) {console.error('读取文件失败:', error);throw error; } }};写入文件
使用方式
# 创建新文件"创建一个新文件 test.py,内容是 print('hello')"# 追加内容"在日志文件末尾添加一行'任务完成'"# 覆盖文件"重写 README.md,标题改为'项目说明'"技能实现
module.exports = {name: 'write-file',asyncexecute({ filePath, content, mode = 'overwrite' }) {try {if (mode === 'append') {awaitappendFile(filePath, content); } else {awaitwriteFile(filePath, content); }return`✅ 文件已写入:${filePath}`; } catch (error) {console.error('写入文件失败:', error);throw error; } }};编辑文件
使用方式
# 精确替换"把 main.py 第 10 行的变量名从 x 改为 count"# 批量替换"把所有文件中的'console.log'改为'logger.info'"# 删除内容"删除 config.json 中的'debug'字段"技能实现
module.exports = {name: 'edit-file',asyncexecute({ filePath, oldText, newText, lineNumber }) {try {let content = awaitreadFile(filePath);if (lineNumber) {// 替换特定行const lines = content.split('\n'); lines[lineNumber - 1] = lines[lineNumber - 1].replace(oldText, newText); content = lines.join('\n'); } else {// 全局替换 content = content.replace(newRegExp(oldText, 'g'), newText); }awaitwriteFile(filePath, content);return`✅ 已编辑文件:${filePath}`; } catch (error) {console.error('编辑文件失败:', error);throw error; } }};📝 实用场景
场景 1:项目初始化
示例:自动创建项目结构
module.exports = {name: 'init-project',asyncexecute({ projectName, template = 'node' }) {try {const baseDir = `~/projects/${projectName}`;// 1. 创建目录结构awaitmkdir(`${baseDir}/src`);awaitmkdir(`${baseDir}/tests`);awaitmkdir(`${baseDir}/docs`);// 2. 创建基础文件if (template === 'node') {awaitwriteFile(`${baseDir}/package.json`, createPackageJson(projectName));awaitwriteFile(`${baseDir}/src/index.js`, createIndexJs(projectName));awaitwriteFile(`${baseDir}/README.md`, createReadme(projectName)); }// 3. 创建.gitignoreawaitwriteFile(`${baseDir}/.gitignore`, getGitignore(template));return`✅ 项目已创建:${baseDir}`; } catch (error) {console.error('创建项目失败:', error);throw error; } }};使用方式
"创建一个新项目 my-app,使用 Node.js 模板"场景 2:批量重命名
示例:批量修改文件扩展名
module.exports = {name: 'batch-rename',asyncexecute({ dir, fromExt, toExt }) {try {const files = awaitlistFiles(dir, `*.${fromExt}`);let renamed = 0;for (const file of files) {const newPath = file.replace(`.${fromExt}`, `.${toExt}`);awaitrename(file, newPath); renamed++;console.log(`重命名:${file} -> ${newPath}`); }return`✅ 共重命名 ${renamed} 个文件`; } catch (error) {console.error('批量重命名失败:', error);throw error; } }};使用方式
"把 pictures 目录下所有 JPG 文件改为小写 jpg 扩展名""把所有.txt 文件改为.md"场景 3:代码统计
示例:统计项目代码行数
module.exports = {name: 'code-stats',asyncexecute({ dir }) {try {const files = awaitlistFiles(dir, '*.{js,py,go,rs}');let totalLines = 0;let totalFiles = 0;const stats = {};for (const file of files) {const content = awaitreadFile(file);const lines = content.split('\n').length;const ext = file.split('.').pop(); totalLines += lines; totalFiles++;if (!stats[ext]) { stats[ext] = { files: 0, lines: 0 }; } stats[ext].files++; stats[ext].lines += lines; }returnformatStats(totalFiles, totalLines, stats); } catch (error) {console.error('代码统计失败:', error);throw error; } }};functionformatStats(files, lines, stats) {let result = `📊 代码统计\n\n`; result += `总文件数:${files}\n`; result += `总行数:${lines}\n\n`; result += `按语言统计:\n`;for (const [ext, data] ofObject.entries(stats)) { result += ` .${ext}: ${data.files} 文件,${data.lines} 行\n`; }return result;}输出示例
📊 代码统计总文件数:45总行数:5,230按语言统计: .js: 25 文件,3,100 行 .py: 15 文件,1,800 行 .go: 5 文件,330 行场景 4:自动备份
示例:定时备份重要文件
module.exports = {name: 'auto-backup',asyncexecute({ sourceDir, backupDir, schedule = 'daily' }) {try {const timestamp = newDate().toISOString().replace(/[:.]/g, '-');const backupPath = `${backupDir}/backup-${timestamp}`;// 1. 创建备份目录awaitmkdir(backupPath);// 2. 复制文件awaitcopy(sourceDir, backupPath, {recursive: true,exclude: ['node_modules', '.git', '*.log'] });// 3. 压缩备份awaitcompress(backupPath, `${backupPath}.zip`);// 4. 清理旧备份(保留最近 7 天)awaitcleanupOldBackups(backupDir, 7);return`✅ 备份完成:${backupPath}.zip`; } catch (error) {console.error('备份失败:', error);throw error; } }};使用方式
"每天凌晨 2 点备份 projects 目录到/backup""备份我的工作文档,排除 node_modules"场景 5:文件搜索
示例:按内容搜索文件
module.exports = {name: 'search-files',asyncexecute({ dir, keyword, filePattern }) {try {const files = awaitlistFiles(dir, filePattern || '*');const results = [];for (const file of files) {const content = awaitreadFile(file);if (content.includes(keyword)) {const lines = content.split('\n');const matches = []; lines.forEach((line, index) => {if (line.includes(keyword)) { matches.push({line: index + 1,content: line.trim() }); } });if (matches.length > 0) { results.push({ file, matches }); } } }returnformatResults(results); } catch (error) {console.error('文件搜索失败:', error);throw error; } }};functionformatResults(results) {if (results.length === 0) {return'❌ 未找到匹配的文件'; }let result = `🔍 找到 ${results.length} 个文件\n\n`; results.forEach(item => { result += `📄 ${item.file}\n`; item.matches.slice(0, 5).forEach(match => { result += ` 第${match.line}行:${match.content}\n`; }); result += '\n'; });return result;}使用方式
"在项目中搜索'TODO'标记""查找所有包含'console.log'的 JavaScript 文件""搜索包含'password'的配置文件"🛡️ 安全注意事项
1. 权限控制
{"skills":{"file-write":{"enabled":true,"allowedDirs":["~/projects","~/documents"],"forbiddenDirs":["~/.ssh","/etc","/system"]},"file-delete":{"requireConfirmation":true}}}2. 操作确认
// 危险操作前确认if (isDangerousOperation(filePath)) {const confirmed = awaitconfirm(`⚠️ 确定要${operation}${filePath} 吗?此操作可能不可恢复。` );if (!confirmed) {return'已取消操作'; }}3. 备份机制
// 编辑前先备份asyncfunctionsafeEdit(filePath, editFn) {const backupPath = `${filePath}.backup.${Date.now()}`;awaitcopy(filePath, backupPath);try {returnawaiteditFn(filePath); } catch (error) {// 出错时恢复awaitcopy(backupPath, filePath);throw error; }}📊 文件操作检查清单
执行文件操作前,对照检查:
确认文件路径正确 检查是否有写入权限 危险操作已确认 已创建备份(如需要) 不会覆盖重要文件 操作可撤销或有回滚方案
✅ 学完这篇你能做什么
学完 Day 11,你将能够:
✅ 读写和编辑文件 ✅ 创建项目结构 ✅ 批量重命名文件 ✅ 统计代码行数 ✅ 自动备份文件 ✅ 按内容搜索文件
🔜 下篇预告
Day 12:网络搜索与调研:信息搜集和报告生成
🔍 网络搜索技巧 📊 数据分析方法 📝 报告生成模板
💬 互动环节
你最想用文件管理功能解决什么问题?留言分享!
公众号:OpenClaw 研习社
系列:OpenClaw 30 天入门到精通
作者:OpenClaw 研习社
夜雨聆风