我一直觉得Shell 下面处理文本真正拉开效率差距的不是你背了多少命令而是有没有把正则表达式和 grep、sed、awk 当成一套组合拳来用。很多人单个命令都认识——grep 会过滤sed 会替换awk 会取列——但一到真实场景比如从几万行日志里揪出异常、批量改一堆配置文件、统计某个接口的平均耗时就不知道从哪下手最后要么打开 Python 写脚本要么直接手工翻文件。这篇文章就是想把三剑客这套核心能力彻底打通不光是罗列参数而是讲清楚每个命令背后的处理模型、正则的底层规则、以及它们组合起来该长什么样。适合三种人刚入门 Shell 但总感觉命令“一学就会、一用就废”的新手用过三剑客但始终停留在复制粘贴水平的普通使用者还有需要在日常运维和数据处理里少写点代码、多省点时间的开发或运维同学。1. 先想清楚三剑客到底各管哪一摊1.1 三个工具的定位和分工很多人把 grep、sed、awk 一锅炖总觉得它们都是“处理文本的”用哪个都行。这是最大的误区。三剑客虽然经常出现在同一条管道里但它们的核心定位完全不同。grep负责“找”。它从输入中筛选出匹配正则的行输出的是整行、匹配片段或者符合条件的文件名。它不改内容只是过滤器。sed负责“改”。它是流式编辑器一行一行读完按规则执行增删改操作再把结果输出。它最擅长做行级别和字符串级别的编辑。awk负责“算”。它在按行读取的基础上天然把每行拆成字段支持条件判断、变量、数组、循环和格式化输出。它更像一门小型数据处理语言。用一个生活中的例子说明把文本文件想象成流水线上的零件盒。grep 是质检工只挑出标签合格的盒子sed 是改造工把盒子上的贴纸撕掉、重新贴标签、把不合格的盒子扔掉awk 则是统计员不仅看标签还要按零件型号计数、算平均值、把结果重新排版。三者一起配合的时候流水线效率才最高。1.2 正则表达式与三剑客的关系正则表达式是这整套组合拳的地基但三剑客对正则的“理解程度”不一样这恰恰是新手最容易翻车的地方。grep 默认使用基本正则表达式BRE意思是()、{}、|这些元字符在默认模式下会当成普通字符处理。要启用扩展正则表达式ERE得用grep -E或者egrep。sed 默认也是 BRE但它的替换命令里可以用-E参数切换成 ERE。awk 则比较大方默认就是 ERE。这里有一个非常容易踩的坑在 grep 里写grep (error|warning) log.txt它不会匹配 error 或 warning而是在找字面意义的括号字符。必须写成grep -E (error|warning)或者转义grep \(error\|warning\)。我见过不少人在这上面浪费半小时最后以为是文件问题其实只是漏了-E。下面这个表格基本能说清 BRE 和 ERE 的差异对日常使用的影响元字符BRE 默认行为ERE 行为举例()分组需要写成\(\)直接用()grep \(ab\)\vsgrep -E (ab){}量词需要写成\{\}直接用{}sed s/[0-9]\{3\}/x/vssed -E s/[0-9]{3}/x/ 或逻辑需要写成|直接用|、?不支持除非转义原生支持grep -E so我个人的习惯是只要正则稍微复杂一点就无脑加-E让 grep 和 sed 都用 ERE避免在转义上纠结。awk 天生用 ERE事情就少了一大半。2. 正则表达式这是所有文本处理的地基2.1 字符匹配与位置锚定正则的核心能力可以拆成三块匹配什么字符、匹配多少个字符、在什么位置匹配。三者叠加基本能表达绝大多数文本模式。字符匹配这块除了直接写字母和数字日常最常用的就是字符类和预定义字符类。比如[0-9]表示任意数字[a-zA-Z]表示任意字母[^0-9]表示非数字。这里注意字符类里面的^是取反的意思但它在字符类外面又是行首锚点同一个符号在不同位置含义不同初学的时候很容易混。预定义类中[[:space:]]匹配所有空白字符[[:alnum:]]匹配字母数字[[:digit:]]匹配数字。有些教程喜欢写\d、\w这是 Perl 风格正则的写法在 grep、sed 的默认模式里并不通用。如果你用grep -P可以支持 Perl 正则但-P在部分系统上不一定可靠所以我建议在 Shell 里老老实实用 POSIX 字符类。位置锚定是另一个高频点。^匹配行首$匹配行尾。比如grep ^#找注释行grep error$找行尾是 error 的行。这里要注意在 Shell 里用双引号包正则时$会被 shell 当成变量符号展开所以正则里有$的时候要么用单引号要么转义。我见过有人写grep error$ file结果 shell 把error当成变量名去取值正则彻底变了味。2.2 量词与分组引用量词解决的是“匹配多少个”的问题。*表示前一个字符出现 0 次或多次表示 1 次或多次?表示 0 次或 1 次{n,m}表示出现 n 到 m 次。这组规则看起来简单但和 BRE/ERE 的差异结合后不熟练的人就会在转义上反复踩坑。这里要特别提醒一下“贪婪匹配”的概念。默认情况下*和都是贪婪的会尽量多地匹配字符。比如文本是bhello/b world bok/b你用grep -oE b.*/b它会把整段都匹配出来而不是第一个bhello/b。原因是.*很贪婪会一路吃到最后一个/b才罢休。这个坑在提取网页片段、日志字段时尤其常见后面我会给具体解法。分组引用是正则的进阶利器。用()把一部分模式包起来之后可以用\1、\2引用第 1、第 2 个分组匹配到的内容。sed 的替换命令就是靠反向引用实现“把某段内容抽出来重组”的。例如echo hello_world.sh | sed -E s/(.*)\.(.*)/\2 file is \1/这段命令把文件名拆成主名和扩展名然后调换了顺序。实际场景里反向引用最常用于从日志里提取 IP、从配置里提取键值对、批量重命名文件。2.3 最容易踩的正则坑正则本身的坑我总结下来主要是三个。第一个是贪婪匹配带来的“越界提取”。解决方案是尽量用排除型字符类替代.*。比如要提取两个引号之间的内容写([^]*)就比(.*)安全得多因为前者明确要“非引号字符”到了下一个引号就停不会越界。第二个是转义的层级问题。一个正则表达式要经过 shell 解析、工具解析两重关卡。单引号包裹时 shell 不做任何替换双引号里则要小心$、反引号、\。另外正则里要匹配字面意义的点号就得写\.但在 sed 替换命令里如果替换内容包含/又要考虑分隔符转义。建议是正则统一用单引号sed 的分隔符尽量换成#或|避开/。第三个是中文和 Unicode。POSIX 字符类对中文支持不友好[[:alpha:]]不一定能识别汉字。匹配中文时更可靠的是直接写下中文片段本身或者按字节范围去模糊处理。grep 匹配中文时还要注意 locale 设置LANGC和LANGen_US.UTF-8下的行为可能不同。遇到“正则明明对的但匹配不到中文”的情况先检查locale。3. grep从会用到用得精3.1 grep 实用参数详解grep 是三个命令里使用频率最高、门槛最低的但很多人只会grep keyword file浪费了它一大半能力。先说要加的参数-E启用扩展正则强烈建议写复杂正则时加上。-v反向匹配找“不包含”关键字的行。-i忽略大小写。-n显示行号。-c统计匹配行数而不是打印内容。-o只打印匹配到的部分不打印整行。-A、-B、-C显示匹配行的后几行、前几行、前后几行。-r递归搜索目录。--include和--exclude限定或排除文件类型。-l只输出包含匹配内容的文件名。举个例子我想在项目中找所有 Java 代码里调用httpClient的地方同时排除测试文件可以这样grep -rn --include*.java --exclude*Test.java httpClient src/这个命令在代码审查和故障排查时非常常用。相比直接grep -r扫所有文件--include能大幅减少噪音也避免误搜到编译产物。再比如查 nginx 日志里 500 错误附近的内容前后各看 3 行grep -n -C 3 500 /var/log/nginx/access.log带上-C可以帮你快速还原上下文而不是只看孤零零一行错误。3.2 grep 与正则的配合grep 最常见的正则场景就是“过滤 提取”。过滤用-E写匹配条件提取用-o把符合条件的片段单独拎出来。比如要从访问日志里统计所有出现过的 IPv4 地址可以这样grep -oE ([0-9]{1,3}\.){3}[0-9]{1,3} access.log | sort | uniq -c | sort -rn这条命令里的正则([0-9]{1,3}\.){3}[0-9]{1,3}会把形如 192.168.1.1 的地址匹配出来-o让它只输出 IP 本身然后用管道排序、去重计数、再按数量倒序。这是典型的三剑客管道组合一句命令行统计 Top IP。同样的思路可以扩展到提取所有 URL 里的域名、提取引号里的请求路径、提取所有时间戳。关键是先把“要提取什么”翻译成正则再决定用-o还是awk取字段。3.3 实战中的过滤问题使用 grep 过滤时两个问题特别典型。第一个是“我想找没生效的配置但偏偏匹配到了注释”。比如找配置里所有enabled但注释里也有一堆# enabled false。这时可以用反向过滤加正向匹配的组合grep -E enabled config.conf | grep -v ^\s*#先用 grep 找出包含 enabled 的行再用 grep -v 排除掉以空白开头加 # 注释的行。这个管道写法比用一条复杂正则去兼容两种情况要清晰得多也容易排查问题。第二个是递归搜索大量文件时二进制文件会产生一堆乱码干扰。加参数-I可以忽略二进制文件或者用--binary-fileswithout-match。另外搜索大文件时记得加--line-buffered配合管道否则 grep 会自己缓冲输出在流式处理日志时延迟会很高。4. sed流式文本编辑4.1 sed 的核心工作模型sed 和人们熟悉的“文本编辑器”最大的区别在于它不把整个文件加载到内存里而是逐行读入在“模式空间”里处理完一行就输出一行然后读下一行。这个流式模型决定了它适合处理大文件、适合放在管道中间做实时编辑。sed 的常用命令不多p打印、d删除、s替换、a追加、i插入、c整行替换。命令可以带地址范围比如3,5d删除第 3 到 5 行/error/d删除所有包含 error 的行。一个很容易被忽略的点是sed 不加-n时默认会把每个读入的行都输出一遍然后再执行命令。所以sed s/foo/bar/ file会打印所有行其中 foo 被换成 bar。我想只打印被处理过的行时要加-n再用p命令。这也是为什么很多人用 sed 觉得输出“多了一倍”的原因。4.2 替换命令与反向引用s 命令是 sed 里最常用的。格式是s/正则/替换内容/标志。标志里g表示全局替换没有g则每行只替换第一个匹配I表示忽略大小写p表示打印替换后的行w表示把结果写入文件。反向引用是 s 命令的灵魂。举个例子一个文件里有很多形如2025-03-15 12:30:45 [ERROR] message的日志现在要把所有时间里的中划线换成斜杠sed -E s/([0-9]{4})-([0-9]{2})-([0-9]{2})/\1\/\2\/\3/ log.txt这里用分组捕获年月日替换内容里\1、\2、\3引用了三段数字。注意替换内容里的/需要转义所以我把分隔符还是保留/但要写\/容易晕。更优雅的做法是换分隔符sed -E s#([0-9]{4})-([0-9]{2})-([0-9]{2})#\1/\2/\3# log.txt当替换内容里包含大量斜杠时换成#或|作为分隔符可读性瞬间提升。4.3 批量替换与原地修改的坑sed 的-i参数可以直接修改文件日常批量改配置时非常爽但也有几个容易出事的细节。最常见的坑是平台差异。Linux 自带的 GNU sed 支持sed -i s/foo/bar/ file但 macOS 的 BSD sed 要求写成sed -i s/foo/bar/ file多一个空字符串参数表示不生成备份。如果你在 macOS 上直接套用 Linux 写法会报错。跨平台脚本里最好统一用sed -i.bak s/foo/bar/ file这样既能生成备份两个平台都兼容。另一个坑是-i原地修改会直接改原文件一旦替换内容写错数据很难恢复。我的习惯是每次批量改文件前先不带-i跑一次把输出重定向到临时文件看一眼确认无误再真正加-i。尤其是用find批量替换时最好配合备份后缀find /etc/nginx/conf.d -name *.conf -exec sed -i.bak s/worker_processes [0-9]*/worker_processes 4/ {} \;这段命令会把所有 nginx 子配置里的 worker_processes 改成 4同时每个文件生成一个.bak备份。关于跨行处理sed 其实能做到多行模式操作比如用N把下一行并入模式空间再用P、D处理。但说实话日常脚本里我很少用这些高级命令因为可读性很差而且一旦逻辑复杂awk 能写得更清晰。sed 适合的是“明确的单行改动”跨行模板匹配的活交给 awk 或者干脆用 Python 才是更合理的选择。5. awk结构化数据处理利器5.1 awk 的工作模型和内置变量awk 是所有文本处理命令里最接近一门编程语言的存在。它的模型是按行读取自动把每行按分隔符切成若干字段然后对每一行执行pattern { action }。没有指定 pattern 时每一行都执行 action没有 action 时默认打印整行。awk 的内置变量是理解它的钥匙变量含义$0整行内容$1、$2…第 1、第 2 个字段NF当前行的字段总数NR当前是第几行FS输入字段分隔符默认空白OFS输出字段分隔符默认空格RS输入记录分隔符默认换行ORS输出记录分隔符默认换行默认字段分隔符是空白包括空格和 Tab。如果日志是逗号分隔的 CSV可以用-F,指定。比如处理一个 CSV 文件想打印第二列和第五列之间的逗号可以这样awk -F, {print $2 , $5} data.csv或者更规范地设置 OFSawk -F, BEGIN{OFS,} {print $2, $5} data.csv这里 BEGIN 块在读取任何行之前执行适合初始化变量和输出格式。5.2 过滤、汇总与格式化输出awk 比 grep 和 sed 更厉害的地方在于它可以在读取行时做数值计算。这是命令行里做日志统计的杀手级能力。比如一个访问日志文件每行最后一列是请求耗时秒现在想计算所有请求的平均耗时。可以直接awk {sum $NF} END {print sum / NR} access.log再看每秒、每接口的状态码统计。假设日志格式是192.168.1.10 - - [12/Oct/2025:13:55:36 0800] GET /api/user/list HTTP/1.1 200 1024 Mozilla 0.214那么$1是 IP$9是状态码$12是耗时。统计所有状态码出现次数可以awk {cnt[$9]} END {for (code in cnt) print code, cnt[code]} access.log这个写法用了数组cnt[$9]表示以状态码作为下标累加。在 END 块里遍历数组输出每种状态码和对应的次数。比起grep | uniq -c的组合awk 一条命令就完成了统计而且只扫描一遍文件。再复杂一点找出耗时超过 2 秒的请求只输出 IP、接口和耗时可以这样awk $12 2 {print $1, $7, $12} access.log注意字段$7是接口路径。awk 的 pattern 部分可以任意组合条件比如$9 500 $12 1这就是“状态码是 500 且耗时超过 1 秒”的错误请求一条命令过滤加格式化输出全搞定。5.3 awk 中的正则与函数awk 默认就支持扩展正则所以前面 grep 里那些正则规则都能直接用。但 awk 里的正则使用姿势有它的特点。常用的写法有几种/正则/作为 pattern匹配整个行。$9 ~ /^5/匹配某字段。$9 !~ /^5/不匹配某字段。match($0, 正则)函数提取匹配位置。sub()、gsub()函数做替换。split()函数按指定分隔符把字符串切成数组。举个例子从日志里提取追接口/api/user/list的平均耗时awk $7 ~ /^\/api\// {sum $NF; count} END {print sum/count} access.log这里正则^\/api\/匹配以/api/开头的接口路径。awk 的替换函数也很有用比如把文件里的所有逗号替换成 Tabawk {gsub(/,/, \t); print} data.csv注意gsub改的是$0所以后面直接 print 就是替换后的整行。5.4 awk 也是语言流程控制和自定义函数awk 的进阶用法是大规模统计和数值处理。它支持if、for、while循环甚至能自定义函数。这意味着很多原本要写 Java、Python 脚本干的活用 awk 一行就能完成。比如我想统计每个接口的请求次数并输出排名前 5awk {cnt[$7]} END {for (endpoint in cnt) print cnt[endpoint], endpoint} access.log | sort -rn | head -5这里 awk 负责聚合sort负责排序。如果你想完全不用外部命令可以把数据存进数组然后在 END 里排序但代码会复杂不少。实际情况中我倾向于“让 awk 做它最擅长的分组统计让 sort 做排序”各取所长。awk 还有一个优势是格式化输出。printf可以让你像写 C 语言一样控制输出格式。比如awk {printf %-15s %6d %8.2f\n, $1, $9, $12} access.log | head%-15s左对齐 15 个字符%6d右对齐整数%8.2f保留两位小数的浮点数。日志分析结果直接变成对齐的表格视觉感受完全不同。6. 组合拳实战一个完整的日志分析流程6.1 场景背景与目标前面拆完单个工具现在把它们串起来。假设我们现在要做一个典型的 nginx 日志分析日志格式和上面一致。需求有三个找出最近 5 分钟内所有 5xx 错误统计访问量最高的 Top 10 IP计算每个接口的平均耗时。这几个需求单靠任何一套工具都不够优雅但是组合起来每个工具都发挥优势整套流程只需要几条命令加一个小脚本。6.2 多命令管道组合先找最近 5 分钟内的 5xx 错误。这里假设日志按时间递增且每行第 4 个字段是时间戳。要精确比较时间得先提取出日期和时间再用 awk 做数值判断。不过这里为了展示思路我用一个简化的方案先 grep 出所有 5xx再查看最近的错误行。grep -E 5[0-9][0-9] access.log | tail -50这个正则 5[0-9][0-9]匹配引号后的状态码5 开头后面跟两位数字。tail -50看最近 50 条。之所以不用awk单独做时间过滤是因为时间字符串“12/Oct/2025:13:55:36”要转成可比较的数字很费劲。实际生产环境里更推荐用tail -F配合管道实时过滤tail -F access.log | grep -E 5[0-9][0-9] 第二个需求统计访问量最高的 Top 10 IPawk {print $1} access.log | sort | uniq -c | sort -rn | head -10这个管道非常经典。awk 提取第一个字段 IPsort把相同 IP 排到一起uniq -c计数sort -rn按数字倒序head -10取前 10 个。第三个需求计算每个接口的平均耗时。这就要用 awk 的分组功能了awk {sum[$7] $NF; count[$7]} END {for (e in sum) if (count[e] 0) printf %-40s %8.3f\n, e, sum[e]/count[e]} access.log | sort -k2 -rn | head -10解释一下数组sum累加每个接口的耗时总和count记录每个接口出现次数。END 块里遍历接口用printf格式化输出接口名和平均耗时。最后管道给sort -k2 -rn按第二列平均耗时倒序取前 10 个慢接口。6.3 写成脚本结构化、可复用命令一多在终端里反复敲就麻烦了而且日志文件路径一换就要改动。更合理的做法是把这套组合逻辑写成一个 Shell 脚本支持传入日志文件路径。下面是一个最小可用的脚本示例#!/bin/bash # 用法: ./analyze_log.sh /var/log/nginx/access.log LOG_FILE${1:?用法: $0 日志文件路径} echo 5xx 错误数 grep -cE 5[0-9][0-9] $LOG_FILE echo Top 10 IP awk {print $1} $LOG_FILE | sort | uniq -c | sort -rn | head -10 echo 接口平均耗时 Top 10 awk {sum[$7] $NF; count[$7]} END { for (e in sum) { if (count[e] 0) { printf %-40s %8.3f\n, e, sum[e] / count[e] } } } $LOG_FILE | sort -k2 -rn | head -10这里有一个容易忽略的细节脚本里所有正则和 awk 脚本建议都用单引号包裹这样$1、$NF这些符号在 bash 里不会被当成变量展开。如果你不小心用了双引号bash 会先把$1替换成脚本的第一个参数awk 的逻辑就全乱了。6.4 性能与管道组合的注意事项组合使用三剑客时有一个常见的性能误区在for循环里反复调用 grep 或 awk。比如统计 10 个接口分别出现多少次有人会写for endpoint in /api/a /api/b /api/c; do grep -c $endpoint access.log done这种方式每循环一次就扫一遍整个日志文件。10 个接口就是 10 次全表扫描日志一大会非常慢。正确做法是让 awk 一次性扫完文件在内存里完成所有统计awk {cnt[$7]} END {for (e in cnt) print e, cnt[e]} access.log再比如多个命令之间频繁使用临时文件也会拖慢整体效率。能在一个 awk 里做的逻辑就不要拆成三次用 awk。但也不要走向另一个极端把所有逻辑都塞进一条复杂到没法维护的管道里。我个人的判断标准是“可读性优先性能其次”。日志文件几万行时怎么组合都快当文件大到几百 MB就需要考虑用 awk 单遍扫描取代多管道扫描同时避免不必要的 sort。7. 常见问题排查与避坑手册7.1 为什么我的正则没有生效这是出现频率最高的问题。常见原因有三个忘了加-E导致、|、()被当成普通字符。shell 把正则中的$、\、反引号解析掉了。比如用双引号写$NFshell 直接把它替换成空。字符类写错。比如想匹配数字写了\d但 grep 默认模式不认。排查思路很简单先在命令行里用最小样例测试。例如echo abc123 | grep -E [0-9]确认正则在简单场景下没问题再放到真实文件里。7.2 提取内容总是多出一大段这通常是贪婪匹配的锅。用.*跨过太多字符吃到了预期之外的尾部。解决办法是把“任意字符”换成“非某类字符”。提取引号内容时用[^]*提取括号内容时用[^)]*提取 IP 时用[0-9.]*从根上掐断越界的可能性。7.3 处理 Windows 换行时结果怪异Windows 和 Linux 的换行符不一样Windows 文件每行结尾多一个\r。这会导致 awk 的最后一列数据带着\r数字比较、输出格式都会异常。处理办法是先用 sed 把行尾的\r去掉sed -i s/\r$// file.txt或者直接在 awk 里兼容awk {gsub(/\r$/, , $NF); print} file.txt批量处理目录下所有 Windows 格式文件时也可以用dos2unix但最保险的还是 sed 一行命令三剑客里处处都有 sed 的用武之地。7.4 中文匹配不稳定前面提过中文匹配受 locale 影响很大。执行locale查看当前环境如果LANGC或LC_ALLCgrep 处理 UTF-8 中文可能就会变成按字节乱匹配。希望匹配中文时我建议先设置环境变量export LANGen_US.UTF-8然后直接写中文关键词匹配。例如grep 登录失败 app.log大部分现代系统默认 UTF-8问题不大但如果是老旧服务器或者容器镜像locale 缺失是常有的事值得留个心眼。7.5 三剑客和 Shell 脚本的结合误区最后再提醒一个我自己踩过很多次的坑Shell 脚本里用三剑客时变量传递和正则交互很容易出问题。例如写循环遍历文件再在循环体里用 grep 处理如果文件名包含空格for循环会按空格切分导致 grep 拿到残缺的文件名。在这种场景正确的做法是尽量用while read配合管道find /logs -name *.log -print0 | while IFS read -r -d file; do grep -E FATAL $file done这里-print0和read -d 配合用空字符而不是空格分隔文件名可以安全处理包含空格、特殊字符的文件路径。这种细节看起来不起眼但在生产环境里文件名带空格的情况真的很常见一旦踩到就是批量误报。还有一点经验不要总想着一条命令解决所有问题。三剑客的可读性远比“炫技”重要。我见过有人用一条 200 个字符的 awk 命令实现一个完整报表看起来很厉害但半年后自己都看不懂。把逻辑拆成几条管道或者一个脚本每步输出中间结果排查问题的时候会轻松得多。使用三剑客久了我最大的感受是grep、sed、awk 不是互相替代的关系而是三个相互配合的层次。grep 做粗筛sed 做整形awk 做分析。配合正则这个共同的语言它们能完成大部分日常文本处理工作效率甚至比写 Python 脚本还高。建议你拿到真实日志文件时不要急着复制网上的复杂命令先从“这一行的结构是什么、我要提取哪个字段”开始分析然后一步一步加上过滤条件。组装的次数多了正则和三剑客就会变成你下意识就能调用的能力。
企业数字化 ERP 产品动态
相关推荐
Git合并冲突:从理解HEAD指针到从容解决与预防 我第一次见识到<<<<<<< HEAD的时候,整个人是懵的。那天我敲下git push,git 却弹出一屏CONFLICT (content),然后我打开代码文件,发现里面长满了尖括号和等号线,像有人在我的代码里打了一排排路障。… · 2026/9/26 12:06:49
WorkBuddy 本地部署与配置指南:接入 TaoToken 统一 API 通道的 MCP 飞书实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 12:06:43
PostgreSQL 中文乱码排查:从 client_encoding 到 TaoToken 配置骨架 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 12:06:43
2026 前端开发学习资源全汇总:零基础转行必藏,TaoToken 一站式配置搞定 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 12:46:56
YOLOv5智能垃圾分类系统:从环境配置到部署全攻略 简介:基于YOLOv5的智能生活垃圾分类系统源码,面向计算机视觉、深度学习方向的高校学生,适合作为毕业设计、期末大作业或课程设计的完整参考项目。资源围绕生活垃圾分类检测场景,运用YOLOv5目标检测框架,覆盖数据配置、… · 2026/9/26 12:46:50
算法面试必备:接雨水、无重复字符最长子串、字母异位词刷题详解 如果你正准备算法面试,或者刚开始刷 LeetCode,那么接雨水、无重复字符的最长子串、找到字符串中所有字母的异位词这三道题,你迟早会正面撞上。它们常年出现在热门100题、高频题单和各类“leetcode刷题指南”里,几乎每轮面试季都会… · 2026/9/26 12:46:50
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46