首页 > 解决方案 > 使用 bash 脚本替换多个文件中的密码时转义特殊字符

问题描述

我发现了很多很接近的问题,但不完全适合我的用例,所以不得不打开一个新问题。

猜猜一个系统的密码由多个配置文件中的所有小写和大写字母、数字和特殊字符(az、AZ、0-9、#)组成(主域上的 Web 应用程序使用相同的密码,它的子域和所有相关数据库)。带有密码的此类文件的示例是:

$databases = array (
  'default' =>
  array (
    'default' =>
    array (
      'database' => 'database_name',
      'username' => 'datbase_user',
      'password' => 'yv[48k2)KMGx{g1b',
      'host' => 'localhost',
      'port' => '',
      'driver' => 'mysql',
      'collation' => 'utf8mb4_general_ci',
      'charset' => 'utf8mb4',
      'prefix' => '',
    ),
  ),
);

我正在尝试编写一个 bash 代码,该代码采用自动生成的新密码(使用相同的算法 - 所有小写和大写字母、数字和特殊字符),在各个父域的主目录中找到所有出现的旧密码及其子域并替换为新密码。以下单线工作正常:

grep -rlF "$old_pass" /path/to/directory | xargs sed -i "s/$old_pass/$new_pass/g"

对于仅由字母和数字组成的密码(例如qVYYgB5bRxUYpHg)。然而,虽然该grep部分工作正常,但sed一旦系统将特殊字符添加到生成的密码(例如aN#zDU>lve15Uwqn)中,该部分就会失败,给出:

sed -i "s/$old_pass/$new_pass/g" password.php
sed: -e expression #1, char 37: unterminated `s' command

替换所有出现的现有密码的最佳方法是什么,该密码由存储在多个文件的不同变量中的所有字母、数字和特殊字符组成?

标签: regexawksedspecial-characters

解决方案


您的 sed 表达式是错误的,因为您需要转义方括号[

sed -i 's/yv\[48k2)KMGx{g1b/aN#zDU>lve15Uwqn/g' password.php

为避免 shell 参数扩展,请在sed表达式中使用单引号。

如果要匹配所有字母、数字和特殊字符(假设标点符号),可以使用类字符:

sed 's/[[:punct:][:alnum:]]*/NEWPASSWORKD/g' password.php

推荐阅读