1. 几万行日志里的空行vi 一条命令就能清干净如果你手里有一份几万行的文件名清单、日志导出或者配置文件中间夹着大量空行用图形编辑器打开会卡到怀疑人生滚动条拖半天还找不到规律。这种场景其实特别适合回到终端用 vi或 vim的 ex 命令一次性处理。核心命令就一条:g/^$/d意思是「全局匹配所有空行然后删除」。它不依赖鼠标、不依赖插件在服务器上、在 AIX 上、在任何有 vi 的环境里都能跑。这篇内容面向需要批量整理日志、配置文件和代码文件的开发者重点不是讲 vi 有多强而是把「删除空行」这件事拆成可复制、可校验的动作先确认文件状态再执行命令最后用行数对比验证结果。同时我会给出一套 TaoToken 统一 Key 通道下的配置骨架把模型调用和本地编辑流程串起来方便你在整理文件时顺手让模型帮你做二次检查。整套流程实测下来从打开文件到验证完成几分钟就能搞定。2. 为什么用 vi 处理空行而不是图形编辑器图形编辑器处理大文件时常见问题是加载慢、搜索卡、批量替换容易误伤。vi 的优势在于它是流式处理思维命令直接作用于缓冲区不需要渲染每一行。对于「删除所有空行」这种规则明确的任务vi 的:g全局命令比手动查找替换更稳。这里要先区分两个容易混淆的写法。:g/^$/d匹配的是真正的空行也就是行内没有任何字符。而:g/^s*$/d这种写法在不同环境里含义不一样s在部分正则里被当作普通字符真正表示空白字符应该用\s。所以更稳妥的写法是 删除真正的空行行内无任何字符 :g/^$/d 删除只包含空格或 Tab 的行 :g/^\s*$/d如果你只是想删掉完全空的行用第一条就够了。如果文件里还有「看起来是空行、其实带了几个空格」的行用第二条。我试过在几万行的清单文件上跑:g/^$/d执行瞬间完成保存后行数直接少了一大截。TaoToken 在这里的角色是统一 Key 通道当你需要让模型帮你检查清理后的文件、生成校验脚本或者解释某段配置时不用在多个平台之间切换 Key一个通道就能覆盖模型对话、编码计划和 API 调用。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 配置时注意 API 地址不加 UTM 参数。3. TaoToken 统一 Key 通道的配置骨架在动手清理文件之前先把模型通道配好这样后面验证和二次处理都能直接调用。TaoToken 的配置分两种常见形式一种是给支持 OpenAI 兼容接口的工具用的settings.json另一种是给偏工程化的工具用的config.toml。下面给出可直接复制的骨架。3.1 settings.json 配置骨架{ api_key: 你的_TaoToken_Key, base_url: https://taotoken.net/api, model: claude-sonnet-4-20250514, timeout: 60, max_retries: 3 }这里base_url填 https://taotoken.net/api 不要带任何查询参数。api_key从控制台的 API Keys 页面获取地址是 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。model字段按你实际要用的模型填如果只是做文本校验选一个响应快的就行。3.2 config.toml 配置骨架[provider] name taotoken api_key 你的_TaoToken_Key base_url https://taotoken.net/api [model] default claude-sonnet-4-20250514 max_tokens 4096 temperature 0.2 [retry] max_attempts 3 backoff_seconds 2temperature设低一点做文件校验和命令解释时输出更稳定。max_tokens按你的文件片段长度调整如果只是让模型看几行配置4096 足够。3.3 长期编码场景用 Coding Plan如果你不只是偶尔校验文件而是长期做编码、Agent 任务可以走 Coding Plan入口是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。它适合把模型调用嵌进日常开发流程比如让模型帮你生成 vi 命令、检查清理结果、写行数对比脚本。4. 可复制的 vi 删除空行操作步骤下面按「打开文件 → 确认状态 → 执行删除 → 保存 → 验证」的顺序走一遍。每一步都给命令和预期结果。4.1 打开文件并确认行数先用 vi 打开目标文件vi filenames.txt进入后先不要急着删按Esc确保在普通模式然后输入:set number这会把行号显示出来方便你观察空行分布。接着记录当前总行数:$光标会跳到最后一行状态栏会显示行号比如35000。把这个数字记下来后面验证要用。4.2 执行删除空行命令在普通模式下输入:g/^$/d回车后 vi 会立即处理整个缓冲区。如果文件很大可能会有一瞬间的停顿这是正常的不要以为卡死了就中断。处理完成后你会看到行号重新排列空行消失。如果文件里存在「带空格的空行」改用:g/^\s*$/d4.3 保存并退出确认结果无误后保存:wq如果只是想先看看效果、不保存可以用:q!4.4 用行数对比验证结果保存后回到终端用wc -l对比清理前后的行数wc -l filenames.txt假设清理前是 35000 行清理后是 28000 行说明删掉了 7000 个空行。这个数字应该和你之前在 vi 里观察到的空行数量大致吻合。如果差异很大说明可能误删了非空行需要检查命令是否写错。更严谨的做法是先把原文件备份再对比cp filenames.txt filenames.bak vi filenames.txt # 执行 :g/^$/d 后保存 wc -l filenames.bak filenames.txt输出会同时显示两个文件的行数差值就是删除的空行数。5. 验证请求与成功结果清理完成后除了行数对比还可以用模型做一次语义校验。把清理后的文件片段发给模型让它确认没有误删有效内容。调用时用前面配好的 TaoToken 通道。5.1 用模型对话验证清理结果打开模型对话页面地址是 https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。把清理前后的行数、以及文件的前几行和后几行贴进去问它「这个文件清理空行后行数从 35000 变成 28000前后内容是否连续有没有明显断裂」模型会帮你判断是否存在误删。5.2 用 API 做自动化校验如果你想把校验做成脚本可以用 curl 调 APIcurl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer 你的_TaoToken_Key \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-20250514, messages: [ {role: user, content: 文件清理空行后行数从35000变为28000请判断是否合理并给出校验建议。} ] }返回结果里会包含模型的判断。如果它认为行数变化合理说明清理动作基本正确。注意 API 地址是 https://taotoken.net/api 不要加 UTM 参数。5.3 成功结果的判断标准一次成功的空行清理应该满足三个条件第一行数减少量等于空行数量第二文件首行和末行内容没有变化第三用grep -c ^$ filenames.txt检查剩余空行数为 0。三条都满足就可以确认清理完成。6. 本篇常见错误排查6.1 命令输入后没反应很多人第一次用:g/^$/d时输入完回车发现没动静以为命令错了。其实 vi 正在处理缓冲区文件越大停顿越明显。这时候不要重复输入命令也不要按 CtrlC等它处理完就行。如果确实卡住超过十几秒可能是文件太大或者正则匹配范围过广可以按 Esc 后重新检查命令。6.2 误删了非空行最常见的原因是正则写错。比如把:g/^$/d写成了:g/^s*$/d在某些环境里s被当作普通字符匹配的是「以 s 开头、后面任意字符、以 s 结尾」的行结果删掉了不该删的内容。正确写法是:g/^\s*$/d\s才表示空白字符。如果已经误删用u撤销或者从备份文件恢复。6.3 保存后行数没变化可能是命令没有真正执行。检查一下是否在普通模式下输入的命令是否按了回车。另外如果文件是只读的:wq会失败需要用:w !sudo tee %或者先改权限。6.4 API 调用返回 401说明 Key 不对或者没带上。检查Authorization头里的 Bearer 后面是否是你的 TaoToken KeyKey 是否从 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 正确复制。另外确认base_url是 https://taotoken.net/api 没有多余斜杠或参数。6.5 模型返回内容不完整如果max_tokens设得太小模型输出会被截断。把max_tokens调到 4096 或更高。如果还是不行检查网络是否稳定或者换一个响应更快的模型。7. 把清理流程固化下来清理空行这件事单次操作很简单但如果每周都要处理日志最好把流程固化。我的做法是写一个 shell 脚本把 vi 命令、行数对比和 API 校验串起来#!/bin/bash FILE$1 cp $FILE $FILE.bak vi -c :g/^$/d -c :wq $FILE echo 清理前: $(wc -l $FILE.bak) 行 echo 清理后: $(wc -l $FILE) 行 echo 剩余空行: $(grep -c ^$ $FILE)这个脚本用vi -c直接执行命令不需要手动进入交互模式。跑完之后行数和剩余空行数一目了然。如果还想让模型做二次确认可以在脚本最后加一行 curl 调用把结果发给模型判断。TaoToken 的接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有完整的接口说明和示例。ClaudeCode 相关的配置可以参考 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude_codeutm_campaignrewrite 适合把模型能力嵌进编码流程。整套流程跑通之后你会发现 vi 删除空行只是一个小动作真正有价值的是「命令 验证 模型校验」这个闭环。下次再遇到几万行的文件不用再一个个手动删了。