You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将.bash_history按命令分类到独立文件的脚本优化问题

优化bash历史记录分类与清理脚本

问题根源

你之前的写法grep -E -v "^(${categories[@]})"失效,是因为数组直接展开后会被shell按空格拆分,导致正则表达式格式错误(比如数组含带空格的命令时,会被拆成多个无效模式)。

优化方案

通过统一构建转义后的正则表达式,复用categories数组完成提取和清理操作,彻底避免规则重复定义的问题。

完整脚本

#!/bin/bash

# 定义需要分类的命令列表(支持带空格的命令)
categories=("git" "docker" "docker-compose" "kubectl")

# 历史文件路径,优先用环境变量,否则默认~/.bash_history
BASH_HISTORY="${BASH_HISTORY:-$HOME/.bash_history}"

# 构建正则表达式:转义每个命令的特殊字符,用|连接成有效分组
regex=$(printf "%q|" "${categories[@]}" | sed 's/|$//')

# 1. 提取匹配记录到对应分类文件
for cmd in "${categories[@]}"; do
    # 匹配以当前命令开头的行(\b确保不会误匹配类似gitlab-runner这类命令)
    grep -E "^$cmd\b" "$BASH_HISTORY" >> "$HOME/.bash_history.$cmd"
done

# 2. 从原历史文件移除已分类的记录
# 用临时文件替换原文件,避免直接修改导致的文件损坏
grep -E -v "^($regex)\b" "$BASH_HISTORY" > "$BASH_HISTORY.tmp" && mv "$BASH_HISTORY.tmp" "$BASH_HISTORY"

# 可选:刷新当前shell的历史记录,让修改立即生效
history -r

关键细节说明

  • 正则构建:printf "%q"会自动转义命令中的特殊字符(空格、括号等),确保正则匹配准确;sed 's/|$//'去掉最后多余的分隔符,形成git|docker|docker-compose|kubectl这类有效分组。
  • 边界匹配:\b是单词边界,避免误匹配前缀相似的命令(比如git不会匹配gitlab)。
  • 安全修改:用临时文件替换原历史文件,防止IO异常导致原文件损坏。

扩展调整

如果需要匹配包含命令而非仅开头的记录,只需把提取规则的^$cmd\b改成\b$cmd\b,清理规则的^($regex)\b改成\b($regex)\b即可。

内容的提问来源于stack exchange,提问作者Paul_Capo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:05:32