📦 命令概述
最近遇到了一些需要批量把某个文件夹里面所有的文本文件读取的需求,读取结果包含两个变量,第一个变量是文件名称,第二个变量是每个文本文件的内容。于是就编写了这个命令:readfiles。
readfiles 是一个强大的 Stata 命令,用于批量读取指定文件夹中特定扩展名的所有文件,并将每个文件的内容存储为数据集中的观测值。特别适合处理文本文件、日志文件、代码文件等。
🔧 安装方法
net install readfiles.pkg, from("readfiles.pkg 文件所在的文件夹路径")
|
验证安装
which readfiles help readfiles
|
📁 生成示例数据
首先让我们创建一些示例文件来测试命令:
特别需要注意,文件夹名称里面不要有空格,文件夹路径名称不需要使用双引号。
*- 创建测试文件夹 capture mkdir test_files cd test_files
*- 创建第一个示例文本文件 file open myfile using "example1.txt", write text replace file write myfile "这是第一个示例文件" _n file write myfile "包含一些文本内容:`特殊字符`处理" _n file write myfile "第三行内容" file close myfile
*- 创建第二个示例文本文件 file open myfile using "example2.txt", write text replace file write myfile "第二个文件" _n file write myfile "文件结束" file close myfile
*- 创建日志文件 file open myfile using "data.log", write text replace file write myfile "日志文件开始" _n file write myfile "日志结束" file close myfile
*- 回到原始目录 cd ..
|
🚀 基本使用方法
1. 读取文本文件
readfiles test_files, ext(txt) replace
*- 2. 查看生成的数据集结构 describe
*> Contains data *> Observations: 1 *> Variables: 2 *> ----------------------------------------------------------------------------------------- *> Variable Storage Display Value *> name type format label Variable label *> ----------------------------------------------------------------------------------------- *> filename str19 %19s *> content str31 %31s *> ----------------------------------------------------------------------------------------- *> Sorted by: *> Note: Dataset has changed since last saved.
*- 3. 查看前几行数据 list in 1/2
|
2. 读取日志文件
readfiles test_files, ext(log) replace
|
3. 使用调试模式
readfiles test_files, ext(txt) debug replace
|
📊 查看结果
运行命令后,查看生成的数据集:
*- 查看数据结构 describe
*- 查看前几行数据 list in 1/2
*- 查看文件内容 browse
|
输出示例:
*> +---------------------------------------------------------------+ *> | filename | content | *> |---------------------------------------------------------------| *> 1. | test_files/example1.txt | 这是第一个示例文件 | *> | | 包含一些文本内容:'特殊字符'处理 | *> | | 第三行内容 | *> |---------------------------------------------------------------| *> 2. | test_files/example2.txt | 第二个文件 | *> | | 更多内容:'测试反引号'转义 | *> | | 文件结束 | *> +---------------------------------------------------------------+
|
🔍 高级功能
1. 获取返回结果
readfiles test_files, ext(txt) replace ret list
*- 查看读取的文件数量 di "读取了 " r(filecount) " 个文件" *> 读取了 2 个文件
*- 查看文件列表 di "文件列表: " r(filelist) *> 文件列表: "example1.txt" "example2.txt"
|
2. 处理特殊字符
命令会自动将文件中的反引号 (`) 转换为单引号 (‘),避免 Stata 解释错误。
3. 批量处理多种文件类型
*- 批量处理多种文件类型 cap mkdir "res" foreach ext in txt log { capture readfiles test_files, ext(`ext') replace if _rc == 0 { ren filename filename0 save "res/`ext'_files.dta", replace di "已保存 `ext' 文件结果" } }
*- 再使用 appendall 就可以合并了 appendall res, clear
|
⚠️ 注意事项
- 文件编码:确保文件使用 UTF-8 或 Stata 支持的编码格式
- 内存限制:大文件可能会消耗大量内存
- 文件权限:确保有读取目标文件的权限
- 特殊字符:反引号会被自动转义为单引号
- 文件名称:readfiles 命令后面的文件夹名称不需要加双引号,也意味着文件夹的名字里面不能含有空格、括号等特殊符号
🛠️ 故障排除
常见错误及解决方法:
*- 错误:数据集已存在 readfiles folder, ext(txt) // 需要添加 replace 选项 readfiles folder, ext(txt) replace
*- 错误:找不到文件 readfiles wrong_path, ext(txt) // 检查路径是否正确
*- 错误:无效的文件扩展名 readfiles folder, ext(123) // 使用有效的扩展名
*- 错误:文件夹使用了双引号 readfiles "folder", ext(txt) replace // 错误 readfiles folder, ext(txt) replace // 正确
|
📋 命令语法总结
readfiles folder_path, ext(string) [replace debug]
|
命令源代码
为了便于大家更清楚地了解 readfiles 命令,我还提供了该命令的源代码,感兴趣的小伙伴可以自行学习。
program define readfiles, rclass version 15.1 syntax anything(name=folder), ext(string) [replace debug]
if "`replace'" == "" & _N > 0 { di as error "数据集已存在,请使用 replace 选项替换" exit 1 }
local last_char = substr("`folder'", -1, 1) if "`last_char'" != "/" & "`last_char'" != "\" { local folder "`folder'/" }
local files : dir `"`folder'"' files "*.`ext'"
if `"`files'"' == "" { di as error "在文件夹 `folder' 中没有找到 .`ext' 类型的文件" exit 2 }
clear qui { set obs 0 gen filename = "" gen content = "" }
local i = 1 foreach file in `files' { di as text "正在读取文件: `file'"
tempfile tmpfile tempfile tmpfilefilter local fullpath "`folder'`file'"
qui copy "`fullpath'" "`tmpfile'", replace
qui filefilter "`tmpfile'" "`tmpfilefilter'", from("`") to("'") replace
local content = fileread("`tmpfilefilter'")
if "`debug'" != "" { di as text "处理后的内容预览: " substr(`"`content'"', 1, 100) "..." }
qui { set obs `i' replace filename = "`fullpath'" in `i' replace content = `"`content'"' in `i' }
local i = `i' + 1 }
ret scalar filecount = `=`i'-1' ret local filelist = `"`files'"'
di as result "成功读取了 `=`i'-1' 个 .`ext' 类型的文件" di as result "数据集包含变量: filename (文件名) 和 content (文件内容)" di as text "注意:文件中的反引号已被转义为单引号" end
|
点击这里跳转到 RStata 短书平台获取附件:readfiles:批量读取指定文件夹中特定扩展名的所有文本文件
评论