如何在 PowerShell v2 中匹配和替换 Get-Content 和 Set-Content 对象中的字符串?
How to match and replace strings within Get-Content and Set-Content objects in PowerShell v2?
对 Powershell 相当陌生,一直在努力用更新的版权替换程序集文件中过时的版权。然而,使用下面的函数会用我的新版权文本的重复填充整个数据。
我做错了什么?
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")]
您进行了一场比赛:
$copyrightInData = ($Data -match $copyrightSearchTxt)
那只是 returns 一个包含 1 项的数组:文件中与您的模式匹配的一行。那你运行:
$Data = ($Data -replace $copyrightInData, $newCopyright)
查看整个文件,查找与 $copywriteInData
中定义的模式相匹配的内容,并将其替换为新的文案文本。事情是这样的,这是一个正则表达式(简称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
对 Powershell 相当陌生,一直在努力用更新的版权替换程序集文件中过时的版权。然而,使用下面的函数会用我的新版权文本的重复填充整个数据。
我做错了什么?
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")]
您进行了一场比赛:
$copyrightInData = ($Data -match $copyrightSearchTxt)
那只是 returns 一个包含 1 项的数组:文件中与您的模式匹配的一行。那你运行:
$Data = ($Data -replace $copyrightInData, $newCopyright)
查看整个文件,查找与 $copywriteInData
中定义的模式相匹配的内容,并将其替换为新的文案文本。事情是这样的,这是一个正则表达式(简称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