在 Windows 上用 Unix 工作流:把 grep、管道和脚本带回日常
古董级程序员,大厂出来后一直在创业公司,现在仍活跃在一线做 AI 相关的开发。更完整的更新写在微信公众号「字与码」:工作经历、对新技术的想法,以及这些年走弯路的记录,会不定期发在那里。若觉得博客对你有用,欢迎顺手关注。
WSL 对我最大的价值,不是“Windows 终于能跑 Linux 命令了”。Git Bash、Cygwin、MSYS2 早就能做一部分。
真正的变化是:Windows 终于可以稳定接住一整套 Unix 工作流。
不是零散敲几条命令,而是把搜索、过滤、转换、排序、压缩、上传、预览、定时任务、编辑器和浏览器串起来。Windows 保留桌面效率,Linux 负责文本和自动化。

这篇用一个具体场景讲:半夜收到一条接口错误告警,要从一批日志里找出最近 30 分钟失败最多的接口、用户、错误原因,然后整理成一份可发给同事的 Markdown。
如果只靠鼠标点日志平台,这事会很烦。用 WSL 里的 Unix 工具,十几分钟能形成一套可重复脚本。
先准备一个不花哨的工具箱
我不建议上来就配置复杂 dotfiles。先装一组稳定工具:
sudo apt update
sudo apt install -y \
ripgrep \
jq \
fzf \
fd-find \
bat \
htop \
tree \
make \
shellcheck \
rsync \
moreutils
Ubuntu 里 fd 的命令可能叫 fdfind,可以加一个软链接:
mkdir -p ~/.local/bin
ln -sf "$(command -v fdfind)" ~/.local/bin/fd
确认 ~/.local/bin 在 PATH 里:
echo "$PATH" | tr ':' '\n' | grep "$HOME/.local/bin"
这些工具不新奇,但组合起来很强:
| 工具 | 我主要用它做什么 |
|---|---|
rg | 在源码、日志、Markdown 里快速找东西 |
jq | 处理 JSON 日志、API 响应、配置 |
fzf | 从大量候选里交互选择 |
fd | 比 find 更适合日常找文件 |
bat | 带语法高亮地看文件 |
make | 把常用流程收束成命令 |
rsync | 同步数据和归档结果 |
shellcheck | 给 shell 脚本做基本体检 |
场景:把一堆 JSON 日志变成一页报告
假设我们从日志平台导出了几份 JSON Lines:
logs/
api-2026-06-21-0000.jsonl
api-2026-06-21-0010.jsonl
api-2026-06-21-0020.jsonl
每行大概这样:
{"ts":"2026-06-21T00:12:03+08:00","path":"/api/v1/search","user_id":"u_123","status":500,"latency_ms":834,"error":"upstream timeout"}
第一步,不要急着写 Python。先用命令行摸数据:
head -n 1 logs/*.jsonl | jq .
看最近有哪些 5xx:
jq -r 'select(.status >= 500) | [.ts, .path, .user_id, .status, .error] | @tsv' logs/*.jsonl | head
统计错误最多的接口:
jq -r 'select(.status >= 500) | .path' logs/*.jsonl \
| sort \
| uniq -c \
| sort -nr \
| head -20
统计错误原因:
jq -r 'select(.status >= 500) | .error' logs/*.jsonl \
| sort \
| uniq -c \
| sort -nr \
| head -20
这就是 Unix 工作流的基本感觉:每一步都只做一件小事,输出给下一步。
把命令收束成脚本
摸清楚后,再写脚本。比如 scripts/analyze-api-errors.sh:
#!/usr/bin/env bash
set -euo pipefail
log_dir="${1:-logs}"
out="${2:-api-error-report.md}"
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
jq -r 'select(.status >= 500) | [.ts, .path, .user_id, .status, .error] | @tsv' "$log_dir"/*.jsonl \
> "$tmp/errors.tsv"
{
echo "# API 错误简报"
echo
echo "生成时间:$(date '+%Y-%m-%d %H:%M:%S')"
echo
echo "## 总览"
echo
total="$(wc -l < "$tmp/errors.tsv" | tr -d ' ')"
echo "- 5xx 总数:$total"
echo
echo "## Top 接口"
echo
awk -F '\t' '{print $2}' "$tmp/errors.tsv" | sort | uniq -c | sort -nr | head -10 \
| awk '{count=$1; $1=""; sub(/^ /,""); printf "- %s:%s\n", $0, count}'
echo
echo "## Top 错误原因"
echo
awk -F '\t' '{print $5}' "$tmp/errors.tsv" | sort | uniq -c | sort -nr | head -10 \
| awk '{count=$1; $1=""; sub(/^ /,""); printf "- %s:%s\n", $0, count}'
echo
echo "## 样例"
echo
echo '```text'
head -20 "$tmp/errors.tsv"
echo '```'
} > "$out"
echo "$out"
跑:
chmod +x scripts/analyze-api-errors.sh
scripts/analyze-api-errors.sh logs report.md
然后直接用 Windows 打开:
explorer.exe .
或者用 VS Code:
code report.md
这里 WSL 和 Windows 的关系很自然:脚本在 Linux 里跑,Markdown 在 Windows/VS Code 里看,结果可以复制到飞书、邮件或 issue。
用 Makefile 固化入口
团队里最怕“你运行这个脚本,但参数这样那样”。我通常把常用命令放进 Makefile:
.PHONY: error-report shellcheck
LOG_DIR ?= logs
REPORT ?= report.md
error-report:
./scripts/analyze-api-errors.sh "$(LOG_DIR)" "$(REPORT)"
shellcheck:
shellcheck scripts/*.sh
使用时:
make error-report LOG_DIR=logs REPORT=report.md
make shellcheck
Makefile 不高级,但它让入口稳定。新人不用记复杂参数,CI 也容易接。
fzf 让命令行不那么硬
有时候你不知道要看哪份日志。可以用 fzf 选:
file="$(fd '\.jsonl$' logs | fzf --prompt='log> ')"
bat "$file"
也可以选接口:
path="$(
jq -r '.path' logs/*.jsonl \
| sort -u \
| fzf --prompt='path> '
)"
jq --arg path "$path" 'select(.path == $path)' logs/*.jsonl | less
fzf 的好处是,它把“我先看看有哪些候选”这件事塞回命令行。不是所有东西都要做成 Web UI。
和 Windows 桌面配合,而不是对抗
我现在很少追求“全程只用终端”。该用 Windows 的地方就用 Windows。
比如:
explorer.exe .
打开当前目录。
powershell.exe -Command "Get-Clipboard"
从 Windows 剪贴板取内容。
clip.exe < report.md
把报告复制到 Windows 剪贴板。
start.exe https://example.com
用默认浏览器打开链接。
这些命令适合放在个人脚本里,不适合大量出现在团队构建脚本里。团队脚本最好仍然保持 Linux 可运行。个人效率脚本可以大胆利用 Windows 桌面。
定时任务:先选简单的
如果只是每天早上在本机跑一个脚本,我不建议一上来折腾复杂调度。两个选择:
第一种,用 Windows 任务计划程序调用 WSL:
wsl.exe -d Ubuntu -- bash -lc "cd ~/work/tools && ./scripts/daily-report.sh"
第二种,在 WSL 里用 systemd timer。适合你已经把相关服务都放在 WSL 里。
我的判断:
- 任务要和 Windows 登录、桌面通知、企业软件配合:用 Windows Task Scheduler;
- 任务完全是 Linux 脚本和 Linux 文件:用 systemd timer;
- 任务对团队重要:不要放个人电脑,放服务器或 CI。
一条我长期使用的原则
能用一条命令表达清楚的,先不要写程序。
命令超过三次重复,写脚本。
脚本超过两个人使用,加 Makefile。
脚本开始影响团队交付,加测试和 CI。
需要长期运行,离开本机。
WSL 的意义在这里很清楚:它让 Windows 用户也能使用这条 Unix 演进路径。
不是因为终端更酷,而是因为可组合的文本工具真的能省时间。
小结
我喜欢 WSL 的一个原因,是它没有逼我在 Windows 和 Linux 之间二选一。
日常桌面、浏览器、沟通、Office 还在 Windows。
搜索、过滤、批处理、构建、测试、脚本留在 Linux。
两边需要交接时,用 explorer.exe、clip.exe、code . 这些小桥。
久了以后,工作流会变得很顺:
导日志,管道处理,生成报告,复制出去。
拉代码,跑测试,修脚本,打开结果。
下载素材,批量转换,预览,归档。
这不是怀旧的 Unix 情结。它只是把小工具组合起来,把重复劳动挤掉。
参考资料: