从grep到rea:命令行日志分析工具的字段提取实践
半夜两点我对着一个 1.8GB 的访问日志发呆。我要在几十万条请求里把某次超时链路涉及的所有记录捞出来按请求 ID 拼成完整时间线再看哪个环节耗时异常。第一反应是 grepgrep 也确实把行筛出来了但筛完我还得提取参数、转换时间、按 ID 分组、再做聚合计算——本来一条命令能说清的逻辑被拆成七八个管道片段每次复用都要翻旧命令出来改。这种状态持续了大概两周我彻底忍不了决定写一个专门干这件事的小工具。它叫 rea。rea 是我最近业余时间在维护的一个命令行日志文本分析小工具名字没什么讲究键盘上顺手敲出的三个字母含义就当是 Roughly Extract Anything意思是不管什么格式的日志或文本先把里面的字段抽出来再说。它的定位很窄从日志里定位目标行、提取结构化字段、过滤聚合、再以合适的格式输出。适合每天要翻日志、查线上问题、处理半结构化文本的研发和运维朋友用。这篇文章我会把这套工具的来龙去脉、核心设计、实现细节和踩过的坑完整写出来算是一份从需求到落地的全记录。1. 为什么放着 grep、awk 不用偏要自己写 rea1.1 不是 grep 不行是把复杂的逻辑拼成命令太累grep 是日志分析的第一块敲门砖这点没人反对。但实际排查场景里很少停留在找到包含某关键词的行。更常见的是这样统计每种返回码的数量、把所有超过 500ms 的请求按接口分组、把某个请求 ID 关联的所有服务日志按时间拼起来。拿第一种场景举例传统做法大概是grep HTTP/1.1 access.log | awk {print $9} | sort | uniq -c | sort -rn这行命令本身不长但每一次都要重复造轮子。返回码在第 9 列这个位置靠数出来的一旦前面某个字段加了空格列号全变命令立刻失效。更麻烦的是如果我想让统计返回码分布这件事变成一个可复用的能力grep、awk、sort 这串命令没法优雅地封装。写成 shell 函数吧参数传参、默认值、输出格式都要自己处理维护成本和直接写个小工具差不了太多。1.2 awk 的字段心智模型和日志分析的真实场景有错位awk 确实强大但它的核心抽象是文本行 固定分隔符 列号。日志虽然看起来是空格分隔的若干列实际却是半结构化文本有的是keyvalue有的是 JSON有的是[时间] 级别 消息的前缀结构同一行里还会有带空格的消息体。用列号去描述这些字段本质上是在跟文本的物理布局搏斗而不是跟字段语义搏斗。举个例子一条常见日志2025-02-01 10:00:00.123 INFO request_idabc123 user_id88 eventorder_created cost_ms45用 awk 取 request_id 和 cost_ms得先知道它们在哪个列。而如果哪天日志里插了一个新字段所有列号全部后移排查脚本当场报废。我想要的是一个能直接说我要 request_id 和 cost_ms的抽象而不是第 6 列和第 9 列。1.3 重新发明轮子的边界只做日志分析中最常被重复的那部分写 rea 之前我给自己定了一条纪律只做文本分析领域里最常被重复、又最容易被写错的那部分。具体来说就是四条能力——定位行、提取字段、过滤计算、格式化输出。其他功能全部砍掉不做图表、不做告警、不做任务调度。grep 解决的是哪一行出现了关键词rea 解决的是这个关键词所在的行里结构化的字段到底是什么怎么参与统计和过滤。两者的关系不是替代而是互补。实际上我现在排查问题时经常是先 grep 缩小范围再把命中的几十行交给 rea 做字段提取和聚合。提示任何自研工具都应该先问一句我要解决的问题现有工具的抽象是否匹配。列号匹配不上字段语义这就是 rea 出现的合理理由而不是我比 grep 强。2. rea 的核心设计把文本分析变成一条四段式流水线2.1 定位、过滤、提取、输出四个阶段各干各的事rea 的命令行使用方式围绕一条流水线展开先按模板匹配出感兴趣的行再对提取出的字段做条件过滤然后决定输出哪些字段、以什么格式展示。四个阶段可以自由组合也可以只用到其中一部分。命令形式上我尽量让它自然rea match {{remote_addr}} - - [{{time_local}}] {{method}} {{uri}} {{protocol}} {{status}} {{bytes}} \ --where status 500 \ --fields method,uri,status,cost_ms \ --out table这句话读起来就像一个简化的 SQL从日志匹配特定行筛选状态码大于 500 的记录取出请求方法、URI、状态码和耗时字段以表格展示。设计的时候我反复问自己用户在排查问题时脑子里是怎么想的大部分是从长什么样出发而不是从正则怎么写出发。所以我把长什么样直接作为第一配置项。2.2 模板匹配优先于正则让匹配规则可读、可维护rea 的核心创新点不是新的正则引擎而是把正则包装成模板。用户不用写\S、[\d.:/-]这种符号而是用{{字段名}}占位背后自动生成对应的正则片段。比如要匹配一条 Nginx 访问日志我只需要写{{remote_addr}} - - [{{time_local}}] {{method}} {{uri}} {{protocol}} {{status}} {{bytes}}而不是^(\S) - - \[([^\]])\] (\S) (\S) (\S) (\d) (\d)$前者的字段名本身就是文档后者如果不加注释一周之后没人看得懂。我把这个思路称为用样例说话找一条真实日志把可变部分换成语义占位符这就是规则。实现上每个字段会根据名字和可选的类型推导出正则片段默认类型是非空白连续串对应\S声明了{{time_local:datetime}}就对应一个宽松的时间戳匹配{{body:quoted}}对应带引号的字符串。这样既能保留正则的威力又让 90% 的场景不需要手写正则。2.3 流式处理日志多大内存占用都稳在一个低水位日志文件动辄几个 GB第一版的原型我曾经图省事直接readFileSync结果跑一个 3GB 文件直接吃满内存机器卡到鼠标都动不了。后来老老实实改成流式处理。rea 的处理模型是逐行读入逐行匹配逐行输出。读入一行、处理、丢掉这一行的引用再读下一行。内存在任意时刻只需要保留少量缓冲和当前行的字段对象。在处理一个 5GB 日志时rea 进程的内存常驻维持在 300MB 以内大部分还被输出缓冲占据解析本身的内存开销非常低。这也带来了一个额外好处rea 可以直接配合tail -f消费实时日志不用等文件写完。tail -f app.log | rea match {{time}} {{level}} msg{{message}} --fields time,level,message2.4 输入输出做成可插拔从成堆的文件到结构化数据第一版 rea 只支持读普通文本文件后来我很快加了 stdin 支持因为 tail 管道和日志采集器都要从 stdin 吃数据。再后来发现线上日志经常是.gz压缩状态于是又加了自动识别 gzip 的逻辑文件路径以.gz结尾就直接走压缩流解压。这几个输入源对外暴露的接口完全一致解析逻辑无感知。输出端则维持三种格式table 适合人看json 适合给下游工具消费csv 适合丢进电子表格或再交给 sort、awk 继续处理。多加一种格式的成本远低于在页面上手抄数据。默认输出 json 而不是 table这条是我个人的偏好排查问题时人眼读十行表格有用但一旦数据量超过 50 行机器可读的中间格式远比对齐的表格有价值。所以我让 json 成为默认输出想看表格时用--out table显式指定。3. 从想法到可用rea 的实现要点与参数取舍3.1 为什么选 JavaScript 作为实现语言工具最终是用 JavaScript 写的。原因很实际运行环境通用一台机器只要有浏览器生态配套的运行时环境就一定能跑不需要编译JSON 是它的原生数据格式配置解析零成本它的流式接口写这种逐行处理的逻辑很顺手。用 Go 或 Rust 重新实现一遍性能当然更好但对一个日志分析小工具来说性价比不高。rea 的瓶颈在正则匹配和 I/O而这部分 JavaScript 的底层已经做得很成熟。实践下来单线程处理 500MB 的日志耗时大约在一个可接受的范围对于排查问题来说完全够用。3.2 模板编译成命名捕获组的核心代码逻辑既然模板是核心抽象那模板编译就是最核心的代码模块。逻辑不复杂遍历模板字符串找到{{fieldName}}占位符把它替换成带类型推导的正则片段同时记录字段名。function compileTemplate(template) { const fields []; let pattern ^; let rest template; while (rest.length 0) { const index rest.indexOf({{); if (index -1) { pattern escapeRegExp(rest); break; } pattern escapeRegExp(rest.slice(0, index)); rest rest.slice(index 2); const endIndex rest.indexOf(}}); if (endIndex -1) { throw new Error(模板缺少闭合 }}); } const token rest.slice(0, endIndex).trim(); rest rest.slice(endIndex 2); let [name, type string] token.split(:); const fieldPattern getPatternForType(type.trim()); fields.push(name.trim()); pattern (?${name.trim()}${fieldPattern}); } return { regex: new RegExp(pattern), fields }; } function getPatternForType(type) { const patterns { string: \\S, quoted: ([^]*), number: \\d, word: \\w, datetime: \\d{4}-\\d{2}-\\d{2}[ T]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d)?, ip: (?:\\d{1,3}\\.){3}\\d{1,3} }; return patterns[type] || patterns.string; }这段代码刻意保持简单真正落地时还要处理嵌套占位符、字段名冲突、命名捕获组在旧环境不可用等问题。核心思想是把用户友好的模板概念编译成引擎友好的正则表达一次编译多次匹配性能开销只在启动阶段。3.3 性能优化的几个心得回溯、锚定和尽量少吃字符rea 的性能优化踩过几个实实在在的坑分享出来比结论更有价值。第一个坑是回溯。只要模板里有任意字段用了过于宽泛的匹配规则比如{{anything:.*}}去匹配整行剩余内容遇到没有匹配的行时正则会尝试无数种切分方式最坏情况下能把 CPU 跑满。我在设计默认字段类型时故意让string类型映射到\S而不是.*就是为了避免跨空白匹配带来的回溯爆炸。用户写模板时如果某个字段后面有明确分隔符正则引擎很快就能收敛一旦用.*吃到行尾失败检测的成本陡增。第二个坑是不加锚定。编译模板时我强制给正则加上^和$让整行必须完全匹配。这不仅是语义正确的问题也是性能问题没有锚定的话正则会从行的每一个位置开始尝试匹配浪费大量无谓扫描。锚定之后不匹配的行会在极短时间内失败。第三个坑是字符串切片的时机。早期实现里我会对匹配的行先按空格 split 一次再做字段提取等于多做了一次全量切分。后来改成只用命名捕获组直接定位字段子串需要哪个字段就取哪个字段省掉大量中间结果处理耗时下降了约 30%。3.4 输出格式的细节坑比想象的深JSON 输出看似简单实际有个字段类型问题。日志里提取出来的字段全是字符串但用户希望status是数字、cost_ms是数字、time是时间对象。rea 的配置里允许给字段声明类型输出前做一次类型转换转换失败时保留原始字符串并给出一条 warning而不是默默丢弃。CSV 的坑在转义。字段值里如果包含逗号、引号和换行不处理就会破坏列结构。我实现了一个标准 CSV 转义函数字段含逗号、引号、换行时用双引号包裹内部的引号再翻倍转义。这个逻辑看起来简单但少了它导出的表格在电子表格软件里必然错列。表格输出也有细节列宽由该列最大内容长度决定中文和英文的显示宽度不同纯靠length计算会不对齐。实际实现里我用了一个简单的显示宽度函数把中文字符按双宽度计算才让表格在终端里像样。4. 偶遇真实日志时的三个隐藏坑4.1 文件编码BOM、GBK 与 UTF-8 混在一堆文件里开发阶段我用的都是 UTF-8 编码、无 BOM 的干净测试文件直到某个环境导出的日志给我上了一课。第一个问题是 BOM。Windows 下生成的日志文件开头会带一个不可见的\uFEFF字符。rea 读第一行时模板里的^锚点无法匹配这个隐藏字符导致第一条日志永远解析失败。这不是大问题但非常隐蔽你只会发现整个文件第一条记录神秘消失。修复方案很直接在流开始阶段读取前三个字节如果是 BOM 就剥掉。第二个问题是 GBK。很多老系统的日志默认 GBK 编码尤其日志里包含中文环境名、中文错误消息时不处理直接按 UTF-8 解码输出全是乱码。我的做法是为rea match增加一个--encoding参数底层交给通用的转码模块处理。纯 ASCII 字段其实不受影响但消息体这种自由文本就依赖编码正确。提示处理外部日志前先花十秒确认文件编码。或者干脆在命令里显式加--encoding utf8/--encoding gbk避免环境不同导致的意外差异。4.2 多行日志真正难的不是字段是拼接规则日志领域最经典的坑之一就是多行日志。一个 Java 异常堆栈可以跨十几行每行开头是空格和at关键字一个多行 JSON 日志中间会夹杂大括号嵌套。如果只按行匹配规则永远匹配不上一条完整日志。rea 引入了一个很朴素的拼接策略--join-mode。默认是line按行处理。处理异常堆栈时切换到stack模式它的判断逻辑是如果当前行以若干空格和at开头就把它作为上一行日志的附加内容不做匹配、不额外输出只在需要时把完整原文暴露给输出端。实现这个逻辑要注意一个细节拼接不能无限往内存里堆必须给附加行数量设上限比如最多拼接 200 行超过就强制切开防止个别异常日志拖垮整体内存。4.3 字段漂移不同日志源的格式比想象中碎你以为同一类日志的格式是固定的直到你把 rea 从一个环境挪到另一个环境。某些服务日志字段名是下划线命名某些是驼峰命名某些环境多一个thread_id字段某些环境整个字段缺失。如果规则写死thread_id另一环境匹配直接失败。我在配置里引入了两个解决机制。第一个是字段别名rules: - name: app_log match: {{time}} {{level}} {{msg:body}} aliases: thread: thread_id defaults: thread_id: -第二个是未匹配行不留死角rea 默认把匹配失败的行单独写入--unmatched文件而不是直接丢弃。这样字段漂移发生时你能第一时间从 unmatched 文件里看到新格式而不是在数据分析结果里发现某类数据凭空变少。5. rea 现在的真实用法命令速查与工作流衔接5.1 最常用的几条命令我这几个月用下来高频命令基本就这五类列成表格方便直接抄场景命令说明提取指定字段rea match {{time}} {{level}} msg{{msg}} --fields time,level,msg --out table从日志里抽出关键字段条件过滤rea match {{t}} cost{{cost}} --where cost 1000 --out json筛选耗时超阈值记录分组统计rea match {{t}} url{{url}} status{{status}} --fields url --count统计接口访问次数实时追踪tail -f app.logrea match err{{message}} --fields message排查未匹配rea match ... --unmatched unmatched.log观察日志格式漂移5.2 和其他命令联合作战rea 从不打算替代整个 Unix 工具箱它产出的是中间格式下游用什么都行。我最喜欢的组合是把 filter 和 sort 交给系统命令rea 专注做格式解析这一件小事。# 按耗时从高到低排列超时请求 rea match {{time}} cost{{cost}} api{{path}} --where cost 500 --out csv \ | sort -t, -k2 -rn # 从 1GB 日志中筛出错误级别记录按接口聚合 rea match {{date}} {{level}} api{{path}} --where level ERROR --fields path --count另一个实用技巧是把 rea 的输出格式改为编辑器能识别的定位格式rea match {{time}} {{level}} file{{file}}:{{line}} {{msg}} \ --fields file,line,msg \ --out template --template {file}:{line}: {msg}这样输出的每一行都带上文件路径和行号在大多数编辑器里可以直接跳转到对应源码位置。这个功能是我在排查一个告警脚本时临时加上的后来成了我最常用的隐藏功能。5.3 下一步想扩展的方向rea 现在最缺的是多规则联合匹配。真实排查场景里访问日志、业务日志、错误日志往往分散在不同文件如果能把多个规则包组织成一次任务一次输入、多条输出会更贴近实际工作流。另一个方向是聚合计算的增强。目前只有计数我想加入avg、sum、p50、p90这类简单统计配合--group-by字段让查询日志分布这个高频需求一条命令完成。到时候最常用的命令大概会变成这样rea match {{time}} api{{path}} cost{{cost}} \ --group-by path \ --agg avg(cost),p90(cost),count当然这只是规划具体什么时候写还得看下次排查看日志的时候有多痛。我在实际使用 rea 的过程中最深的体会是一个工具能长期活下去靠的往往不是功能多而是边界清楚。rea 从头到尾只做把文本中的字段结构化这一件事所以它体量小、易维护、敢重构。也许你不需要照抄 rea 的任何代码但如果能从这篇文章里带走一点东西我的建议是如果某个临时脚本被你反复复制粘贴超过三次就把它从一个一次性命令升级成一个有名字的工具给它一个明确的输入输出契约而不是继续往 shell 历史里堆一摞谁也看不懂的长命令。

相关新闻

知识工作插件全解析:从需求到落地的效率提升指南

知识工作插件全解析:从需求到落地的效率提升指南

1. 为什么我盯上了"knowledge-work-plugins"这组关键词先坦白一下我的习惯:平时逛代码仓库、刷技术社区时,我不太喜欢追那种名字特别花哨的项目,反而会对那种一眼看上去就是个"生产力工具集合"的仓库格外来劲。前几天看到…

2026/10/13 16:35:03 阅读更多 →
Element UI 单选/多选框样式修改:scoped 穿透与自定义图标实战

Element UI 单选/多选框样式修改:scoped 穿透与自定义图标实战

前端群里隔三差五就有人问:Element UI 的单选框/多选框怎么改选中样式?默认那个蓝色主题色跟设计稿对不上,圆点大小、边框颜色、选中时的小勾都太“默认”了。其实这类问题不是改不了,而是没搞懂 Element UI 的 radio 和 checkbox…

2026/10/13 16:35:03 阅读更多 →
Codex Token 优化攻略:10 个技巧降低 AI 编程成本

Codex Token 优化攻略:10 个技巧降低 AI 编程成本

1. 为什么 token 消耗值得认真对待1.1 一个被大多数人忽略的成本黑洞用 Codex 这类 AI 编程助手做开发,很多人一开始只关注“能不能跑通”“生成得对不对”,等到月底一看账单或者额度消耗记录,才发现 token 烧得比想象中快得多。我刚开始用的…

2026/10/13 16:35:03 阅读更多 →

最新新闻

荷兰耕地遥感语义分割:从数据标注到模型训练全流程实战

荷兰耕地遥感语义分割:从数据标注到模型训练全流程实战

简介:这份荷兰耕地语义分割遥感影像数据集面向遥感图像处理、计算机视觉与农业监测方向的研究者和开发者,用于训练和验证耕地识别与像素级分割模型。资源包共2000个文件,以xml标注文件为主要类型,对应每张遥感影像的像素级类别标签…

2026/10/13 17:09:08 阅读更多 →
LiteLLM:统一LLM API抽象层实战指南

LiteLLM:统一LLM API抽象层实战指南

1. 项目概述:LiteLLM 是什么,它解决的到底是什么问题? LiteLLM 这个名字乍一听像是某个轻量级编程语言或小众框架,但其实它是一个在大模型应用开发圈子里迅速走红的开源工具库——准确地说,它是一个 统一 API 抽象层…

2026/10/13 17:09:08 阅读更多 →
GitHub日榜不是流量快照,而是可工程化的情报系统

GitHub日榜不是流量快照,而是可工程化的情报系统

1. 这不是“榜单搬运工”,而是一套可复用的 GitHub 热榜日更方法论你点开 GitHub Trending 页面,看到“Today”标签下那排滚动更新的项目——Star 数飙升、语言栏跳动、描述简短却抓人。很多人以为这只是平台自动聚合的“流量快照”,随手点开…

2026/10/13 17:09:08 阅读更多 →
MySQL 8.0.18 本地开发环境搭建与 SQLyog 连接配置实战指南

MySQL 8.0.18 本地开发环境搭建与 SQLyog 连接配置实战指南

1. 为什么本地开发环境首选 MySQL 8.0.18 搭配 SQLyog1.1 版本选型的现实考量MySQL 8.0.18 这个版本在本地开发环境里算是一个比较特殊的存在。它发布于 2019 年底,属于 8.0 系列早期比较稳定的一个版本,既包含了 8.0 大版本带来的窗口函数、CTE&#xf…

2026/10/13 17:09:08 阅读更多 →
C/C++头文件依赖可视化:用gcc-M和Graphviz生成可审计依赖图

C/C++头文件依赖可视化:用gcc-M和Graphviz生成可审计依赖图

1. 为什么C/C项目里“谁依赖谁”总在编译失败后才暴露?我第一次接手一个二十万行的嵌入式图像处理模块时,就栽在这上面。改了三行头文件里的宏定义,make直接报错:error: struct pixel_buffer has no member named stride。奇怪的是…

2026/10/13 17:09:08 阅读更多 →
从零手搓投资Agent:百亿token金融文本的智能决策系统

从零手搓投资Agent:百亿token金融文本的智能决策系统

1. 项目概述1.1 从零手搓投资Agent的动机先说背景。我们团队在开发这套系统之前,已经用传统量化策略跑了将近两年,规则引擎、因子库、事件驱动框架都搭过一遍,但遇到一个很难绕过去的坎:传统策略对“非结构化信息”的处理能力几乎…

2026/10/13 17:08:08 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →