如何在PowerShell v2中匹配和替换Get-Content和Set-Content对象中的字符串?

时间:2018-02-21 22:08:47

标签: powershell powershell-v2.0

Powershell相当新,并且一直在努力用更新版权替换装配文件中的过时版权。但是,使用下面的功能可以重复我的newCopyright文本来填充整个数据。

我做错了什么?

function UpdateCopyright{
param            
(            
    [Parameter(Mandatory=$True,Position=1)]
    [String] $copyrightFileWithPath = "_"
)
try
{
    if ($copyrightFileWithPath -ne "_"){
        $currentYear         = (date).Year
        $copyrightNewTxt     = "Copyright © Company $currentYear"
        $copyrightSearchTxt  = "assembly: AssemblyCopyright"       
        $newCopyright = "[assembly: AssemblyCopyright(""$copyrightNewTxt"")]"
        $Data = (Get-Content $copyrightFileWithPath)          
        $copyrightInData = ($Data -match $copyrightSearchTxt)         
        $Data = ($Data -replace $copyrightInData, $newCopyright)
        Set-Content $copyrightFileWithPath $Data
        return $true
    }
    else{
        Write-Host ("ERROR: Invalid parameter to modify copyright for file " + $copyrightFileWithPath)
        return $false
    }
}
catch
{
    $ErrorMessage = $_.Exception.Message
    Write-Host ("ERROR: Exception while modifying copyright for file " + $copyrightFileWithPath + $ErrorMessage)
    return $false
}
}

示例输入文件:

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[assembly: AssemblyProduct("Test App")]
[assembly: AssemblyCopyright("Copyright © Company 2014 - 2018")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("2.11.0.4")]
[assembly: AssemblyFileVersion("2.11.0.4")]

示例输出文件:

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[assembly: AssemblyProduct("Test App")]
[assembly: AssemblyCopyright("Copyright © Company 2018")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("2.11.0.4")]
[assembly: AssemblyFileVersion("2.11.0.4")]

1 个答案:

答案 0 :(得分:1)

您执行以下匹配:

$copyrightInData = ($Data -match $copyrightSearchTxt)

只返回一个包含1个项目的数组:文件中与您的模式匹配的一行。然后你运行:

$Data = ($Data -replace $copyrightInData, $newCopyright)

查看整个文件,查找与$copywriteInData中定义的模式匹配的内容,并将其替换为新的copywrite文本。这就是事情,这是一个正则表达式(简称RegEx)匹配。所以$copywriteInData是字符串[assembly: AssemblyCopyright("Copyright © Company 2014 - 2018")]。在RegEx中,方括号内的任何内容都意味着它应匹配其中的任何字符,因此当您执行-replace时,它会查看第一个字符并决定:

Does it match: A
Does it match: s
Does it match: s
Does it match: e
Does it match: m

继续进行,直到找到匹配的[ ]内的字符,或者[ ]内的字符用完以匹配。如何解决这个问题是为RegEx匹配正确转义字符串:

$Data = $Data -replace [regex]::Escape($copyrightInData), $newCopyright

更简单的方法是更好地定义要替换的内容,然后只需读取文件,执行替换,然后编写文件。

    $currentYear         = (date).Year
    $copyrightSearchTxt  = '(?<=\[assembly: AssemblyCopyright\(").*?(?="\)])'
    (GC $copyrightFileWithPath) -replace $copyrightSearchTxt, $currentYear | Set-Content $copyrightFileWithPath