【问题标题】:How to Find String in File(s) and Replace a Unknown Number of Characters After It?如何在文件中查找字符串并在其后替换未知数量的字符?
【发布时间】:2017-09-06 00:10:17
【问题描述】:

问题

我正在尝试编写一个复杂的查找和替换方法,目的是递归搜索所有配置文件的目录(由用户提供),并根据是否替换配置文件中的一组选定部分/键一系列复选框被选中。

预期结果/示例

在下面的场景中,我只想用一个新值替换数据库密码(因此其他值对于这个例子并不重要)。

# collect only the configs that contain the section/key names the application is designed to alter
$configs = GCI -Path "$somePath\*.config" -Recurse | Where-Object {
    ((Select-String -Pattern "DatabasePassword") -ceq $true) -OR
    ((Select-String -Pattern "SomeKey02") -ceq $true) -OR
    ((Select-String -Pattern "SomeKey03") -ceq $true)
}

# if the checkbox for Database Password is checked, get the text after its key
if (DBPassword.Checked) {
    foreach ($configFile in $configFiles) {
        GC $configFile | Foreach-Object {
            if ($config -match "DatabasePassword") {
                #I know this next part is sorta right, but I haven't been able to get it to work right
                $tmpStr = $configfile | Out-String
                $start = tmpStr.IndexOf("=") + 2
                $end = $tmpStr.IndexOf('"', $start)
                $length = $end - $start

                $Pass2Replace = $tmpStr.Substring($start, $length)                    
            }
        }
    }
}

# This Next Section is Contained Within a ForEach Loop
# I believe I am Close, but This Doesn't Quite Work
# Parse Through All Config Files and Replace Keys Based On the '.Checked' Status of Each Check Box
(GC $configFiles) | ForEach-Object {
    if ($DBPassword.Checked) {
        ForEach-Object { $_.Replace($Pass2Replace, $newPass.Text) } 
    if ($checkbox02.Checked) {
        ForEach-Object { $_.Replace($Key2Replace02, $newStr02.Text) }
    if ($checkBox03.Checked) {
        ForEach-Object { $_.Replace($Key2Replace03, $newStr03.Text) }
}
# Save Changes
Set-Content $configFile

所以最终,我所期望的结果是用户会选中“更新密码”复选框,在 GUI 文本框中输入新密码,然后单击“更新”按钮。然后,应用程序将查找配置文件,查找键 DatabasePassword,修改存储的值并保存更改。以下是本段的简化版本:

之前:

DatabasePassword = "SomeEncryptedPassword"

之后:

DatabasePassword = "AlteredEncryptedPassword"

问题

主要问题:让 PowerShell 收集这些密钥的未知存储值并仅替换该值的最佳方法是什么?

子问题01:假设主要问题有答案,是否可以只收集一部分存储值并替换它?

示例:假设我有一个名为 ConnectionString 的键,其值为 ((someRandomValue=AWQagaWGAAE#!)(someSetOfStrings)) ;然而,我只想收集值的(someRandomValue=AWQagaWGAAE#!) 部分。我如何只收集这部分并替换它(请记住 someRandomValue 是未知的)?

【问题讨论】:

  • 请在文本前后显示一些示例。正则表达式将大大简化这一点。但是需要具体的例子。
  • @Matt 我修改了帖子以包含一个更相关的示例以及我期望更改的内容
  • 您的 .config 文件的结构是什么?平面文字? INI 风格? XML?
  • “所以我不认为 XML Parser 可以使用它。”你想错了。
  • 我有个好消息,PowerShell XML 解析器! [xml]$MyConfig = GC $ConfigPath 以 XML 格式读入文件。然后,您可以将其通过管道传输到 Select-Xml 以执行 XPath 搜索,或者如果已经知道各种键的路径,您可以执行 $OldDBPass = $MyConfig.Settings.DB1.DatabasePassword$MyConfig.Settings.DB1.DatabasePassword = $NewPass 之类的操作,然后 $MyConfig.Save() 应用更新。

标签: powershell substring str-replace


【解决方案1】:

还没有答案,我想发布一个。我不太明白您的问题,但我想我可以通过 3 条命令行 解决您的基本要求。

根据您的代码 sn-p,您似乎处于 Powershell 环境中,并且您正在使用 *.config 文件在目录 $somepath 中递归搜索和更新。

所以,简要介绍一下您更新DatabasePassword的答案: if ($DBPassword.Checked) { msr.exe -r -p $somepath -f "\.config$" -it "(DatabasePassword)\s*=\s*\S+" -o "`$1 = $newPass.Text" -R }

更新 Key2Replace02 Key2Replace03 也是如此。所以你可能只需要 3 if 并替换命令行。 不用-R可以预览替换,用-K备份;

在我打开的项目https://github.com/qualiu/msrtools 目录中查看msr.exe

您可以添加msr.exe 的一些选项,例如--nd "^(target|bin|\.git|\.svn|obj)$",只需运行msr.exe 或文档站点如:https://qualiu.github.io/msr/usage-by-running/msr-Windows.html (第一次搜索/阅读文件后你会发现它非常快)

【讨论】:

  • 感谢您对我的问题的潜在回答。这是我需要安装/下载的msr.exe,还是它已经是 PowerShell 的一部分?由于工作环境的限制,未经批准,我无法下载/安装任何软件/插件。
  • 只是一个exe文件,没有依赖关系。但是,..,你应该像这样下载它:Invoke-WebRequest -Uri https://github.com/qualiu/msr/blob/master/tools/msr.exe?raw=true -OutFile $your-dir\msr.exe :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-29
  • 2020-11-22
  • 1970-01-01
  • 2018-11-10
  • 2015-08-23
相关资源
最近更新 更多