脚本如何实现文件内容替换正则

wen 实用脚本 1

从入门到高效实战

📖 目录导读

  • 正则替换核心原理:为什么脚本比手动更快?

    脚本如何实现文件内容替换正则

  • 主流脚本语言实现(Shell/Python/Node.js)

  • 实战案例:批量替换配置文件中的敏感信息

  • 常见踩坑与性能优化技巧

  • FAQ:新手最常问的5个问题


正则替换核心原理

在运维、开发、数据处理中,替换正则 是最常用且效率极高的操作,正则表达式(Regular Expression)是一种模式匹配语言,脚本通过读取文件内容、匹配模式、替换文本、写回文件 的流程实现批量修改。

为什么需要脚本?

  • 手动替换数百个文件,不仅耗时且易出错
  • 正则能灵活匹配复杂格式(如日期、IP、特定标签间的文本)
  • 脚本可集成到自动化流水线(CI/CD、定时任务)

核心操作三步骤:

  1. 读取文件到内存或流
  2. 用正则对象执行 replace()sub()
  3. 将结果写回原文件或新文件

主流脚本语言实现

1 Shell(sed 命令,Linux/Mac 首选)

# 将文件中的 "old_text" 替换为 "new_text"(支持正则)
sed -i 's/pattern/replacement/g' file.txt
# 示例:将所有 "192.168.1.1" 替换为 "10.0.0.1"
sed -i 's/192\.168\.1\.1/10.0.0.1/g' config.ini
  • -i 直接修改文件,g 表示全局替换
  • 注意:避免在 Windows Git Bash 下大规模使用,性能受限

2 Python(跨平台,支持复杂逻辑)

import re
with open('data.txt', 'r') as f:
    content = f.read()
# 用正则替换所有数字为 '*'
new_content = re.sub(r'\d+', '*', content)
with open('data.txt', 'w') as f:
    f.write(new_content)
  • 推荐场景:需要捕获组、条件替换、编码处理(如中文UTF-8)
  • 性能:对超过100MB文件建议使用 mmap 逐块处理

3 Node.js(适合与现代前端/后端工作流结合)

const fs = require('fs');
let data = fs.readFileSync('app.json', 'utf8');
// 替换所有双引号内的空格为下划线
data = data.replace(/"([^"]*)"/g, (match) => match.replace(/\s/g, '_'));
fs.writeFileSync('app.json', data);
  • 优势:异步流处理大文件、丰富npm包(如 replace-in-file

实战案例:批量替换配置文件中的敏感信息

场景:公司有100个配置文件需要将数据库密码从明文 password123 改为环境变量引用 ${DB_PASS},且密码可能出现在不同格式中(如 password=123pass:123)。

Python脚本示例(带正则捕获组)

import re, os
pattern = r'(password|pass)[=:]\s*(\S+)'  # 匹配 key=value 或 key:value
replacement = r'\1=${DB_PASS}'  # 保留key,替换value为变量
for root, dirs, files in os.walk('/config'):
    for f in files:
        if f.endswith(('.ini', '.yml', '.json')):
            with open(os.path.join(root, f), 'r') as file:
                content = file.read()
            new_content = re.sub(pattern, replacement, content, flags=re.IGNORECASE)
            with open(os.path.join(root, f), 'w') as file:
                file.write(new_content)
print("替换完成!所有敏感密码已脱敏。")
  • 关键点:使用 IGNORECASE 忽略大小写,捕获组 \1 保留 password 字段

常见踩坑与性能优化

❌ 踩坑1:正则贪婪匹配导致替换错误

  • 错误<div>xxx</div><div>yyy</div> 被 匹配为整个字符串
  • 解法:使用非贪婪 或更精确的 [^>]*

❌ 踩坑2:大文件内存溢出

  • 症状:Python 读取1GB文件时内存飙升至2GB+
  • 优化:使用逐行处理(如 sed、Python fileinput 模块)
    import fileinput, re
    for line in fileinput.input('bigfile.log', inplace=True, backup='.bak'):
      print(re.sub(r'error', 'warning', line), end='')

❌ 踩坑3: Windows/Unix换行符差异

  • 正则中 在Windows下可能不匹配 \r\n
  • 解法:使用 re.MULTILINE + \r\n 或统一转换为Unix换行

⚡ 性能优化公式(按文件大小选择方法):

文件大小 推荐方法 说明
<10MB Python read() 一次性 简单快速
10MB-500MB sedPerl 流式处理
>500MB 分块读写(4KB缓冲区) 避免内存峰值

FAQ:新手最常问的5个问题

Q1:脚本执行后文件变空,如何恢复?

  • 原因:正则匹配失败或写入时覆盖原文件
  • 对策务必先备份,如 cp file.txt file.bak
  • 恢复命令cp file.bak file.txt

Q2:如何替换所有匹配的行,但保留文件结构?

  • 示例:删除所有以 开头的注释行
  • Shell方案sed -i '/^#/d' file.txtd 表示删除行)
  • Python方案:使用 re.sub(r'^#.*\n?', '', content, flags=re.MULTILINE)

Q3:正则中需要替换特殊字符(如 $ . *)怎么办?

  • 解法:使用转义
  • Python raw stringr'\$1.99' 避免反斜杠地狱

Q4:如何测试正则表达式是否匹配正确?

  • 推荐工具regex101.com(实时显示匹配结果)
  • 脚本测试echo "test123" | grep -P "test\d+" (显示匹配行)

Q5:替换后需要保留原文件时间戳?

  • Python方案:使用 os.stat() 先获取时间,写入后 os.utime() 恢复
  • Shell方案touch -r file.bak file.txt 从备份复制时间戳

掌握脚本实现文件内容替换正则,是提升开发效率、保障数据一致性的基础技能,无论是运维批量修改配置,还是数据工程师清洗日志,正则+脚本的组合都能让你在几分钟内完成手动几小时的工作。

建议在日常工作中构建自己的 正则替换工具箱,包含备份、日志输出、异常处理等标准化流程,当你面对数千个文件时,你会感谢今天花10分钟阅读这篇文章的自己。

抱歉,评论功能暂时关闭!