在 Windows 上用 Unix 工作流:把 grep、管道和脚本带回日常
原创 · 约 17 分钟阅读 · 阅读 --

在 Windows 上用 Unix 工作流:把 grep、管道和脚本带回日常

作者: Alex Xiang


古董级程序员,大厂出来后一直在创业公司,现在仍活跃在一线做 AI 相关的开发。更完整的更新写在微信公众号「字与码」:工作经历、对新技术的想法,以及这些年走弯路的记录,会不定期发在那里。若觉得博客对你有用,欢迎顺手关注。

WSL 对我最大的价值,不是“Windows 终于能跑 Linux 命令了”。Git Bash、Cygwin、MSYS2 早就能做一部分。

真正的变化是:Windows 终于可以稳定接住一整套 Unix 工作流。

不是零散敲几条命令,而是把搜索、过滤、转换、排序、压缩、上传、预览、定时任务、编辑器和浏览器串起来。Windows 保留桌面效率,Linux 负责文本和自动化。

Windows 上通过 WSL 串起 Unix 命令行工作流

这篇用一个具体场景讲:半夜收到一条接口错误告警,要从一批日志里找出最近 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从大量候选里交互选择
fdfind 更适合日常找文件
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.execlip.execode . 这些小桥。

久了以后,工作流会变得很顺:

导日志,管道处理,生成报告,复制出去。
拉代码,跑测试,修脚本,打开结果。
下载素材,批量转换,预览,归档。

这不是怀旧的 Unix 情结。它只是把小工具组合起来,把重复劳动挤掉。

参考资料: