Powershell 函数替换文件中的文本并将其保存
我是一名新编程人员,我正在尝试改进脚本的以下代码,我正在考虑制作一个函数来改进它,但我不知道从哪里开始,或者它是否是最佳选择Powershell 函数替换文件中的文本并将其保存,powershell,Powershell,我是一名新编程人员,我正在尝试改进脚本的以下代码,我正在考虑制作一个函数来改进它,但我不知道从哪里开始,或者它是否是最佳选择 $replaceText01 = (Get-Content -path $copyFileLocation -Raw) -replace '"INSTANCENAME="TEST""',$NUEVAINESTANCIA Set-Content $copyFileLocation $replaceText01 $replaceText02 = (Get-Content
$replaceText01 = (Get-Content -path $copyFileLocation -Raw) -replace '"INSTANCENAME="TEST""',$NUEVAINESTANCIA
Set-Content $copyFileLocation $replaceText01
$replaceText02 = (Get-Content -path $copyFileLocation -Raw) -replace '"INSTANCEID="TEST""',$NUEVAINESTANCIAID
Set-Content $copyFileLocation $replaceText02
$replaceText03 = (Get-Content -path $copyFileLocation -Raw) -replace "NT Service\SQLAgent#TEST", $CUENTAAGTN
Set-Content $copyFileLocation $replaceText03
$replaceText04 = (Get-Content -path $copyFileLocation -Raw) -replace "NT Service\MSSQL#TEST", $CUENTASQLSER
Set-Content $copyFileLocation $replaceText04
$user = "$env:UserDomain\$env:USERNAME"
write-host $user
$replaceText = (Get-Content -path $copyFileLocation -Raw) -replace "##MyUser##", $user
Set-Content $copyFileLocation $replaceText
首先,我可能会尝试只读取一次文件。然后,由于您正在执行许多类似的操作,因此我将把有关这些操作的所有数据放在一个数组中,然后对这些数据进行迭代 在这段代码中,我首先读取文件。然后我定义了所有应该被替换的字符串以及应该替换它们的字符串。然后我使用循环对数据进行迭代,这样我们就不会一直重复相同的代码
$data=Get Content-Path$copyFileLocation-Raw
$replacements=@(
@('INSTANCENAME=“TEST”“,$NUEVAINESTANCIA),
@('INSTANCEID=“TEST”“,$numevainestanciaid),
@($NT服务\SQLAgent#测试“,$CUENTAAGTN),
@($NT服务\MSSQL#测试,$CUENTASQLSER),
@(“##MyUser##,“$env:UserDomain\$env:USERNAME”)
)
$replacements | ForEach对象{
$data=$data.Replace($\[0],$\[1])
}
设置内容-路径$copyFileLocation-值$data
如果您使用管道而不是将数据分配给变量,那么也可以缩短时间
$data=Get Content-Path$copyFileLocation-Raw
@(
@('INSTANCENAME=“TEST”“,$NUEVAINESTANCIA),
@('INSTANCEID=“TEST”“,$numevainestanciaid),
@($NT服务\SQLAgent#测试“,$CUENTAAGTN),
@($NT服务\MSSQL#测试,$CUENTASQLSER),
@(“##MyUser##,“$env:UserDomain\$env:USERNAME”)
)| ForEach对象{
$data=$data.Replace($\[0],$\[1])
}
设置内容-路径$copyFileLocation-值$data
编辑:没有注意到您询问如何将其变成函数
通过查看您的操作,我假设您正在修改一个SQL无人参与安装文件,并将其命名为
这里的一个好主意是将大多数参数设置为必需的,这样您就可以确保用户至少指定了所有必需的参数。也许您希望稍后指定MyUser
,因此这是一个很好的具有默认值的参数候选者
函数集SQLInstallFileVariables{
Param(
[参数(必需)][字符串]$FilePath,
[参数(必需)][字符串]$NUEVAINESTANCIA,
[参数(必需)][字符串]$NUEVAINESTANCIAID,
[参数(必需)][字符串]$CUENTAAGTN,
[参数(必需)][字符串]$CUENTASQLSER,
[string]$MyUser=“$env:UserDomain\$env:USERNAME”
)
$data=Get Content-Path$FilePath-Raw
@(
@('INSTANCENAME=“TEST”“,$NUEVAINESTANCIA),
@('INSTANCEID=“TEST”“,$numevainestanciaid),
@($NT服务\SQLAgent#测试“,$CUENTAAGTN),
@($NT服务\MSSQL#测试,$CUENTASQLSER),
@(“##MyUser###,$MyUser)
)| ForEach对象{
$data=$data.Replace($\[0],$\[1])
}
设置内容-路径$copyFileLocation-值$data
}
首先要注意的是,每次替换时都要反复读写文件,这不是很有效。
这是不需要的;一旦读取内容,它就位于字符串变量中,在写回文件之前,可以在内存中进行多次操作
一种方法是使用包含搜索和替换字符串的字符串数组。
要使其正常工作,两个数组必须具有相同数量的元素
$inputFile = 'D:\Test\TheFile.txt' # your input file path here ($copyFileLocation)
$outputFile = 'D:\Test\TheReplacedFile.txt' # for safety create a new file instead of overwriting the original
$searchStrings = '"INSTANCENAME="TEST""','"INSTANCEID="TEST""',"NT Service\SQLAgent#TEST","NT Service\MSSQL#TEST","##MyUser##"
$replaceStrings = $NUEVAINESTANCIA, $NUEVAINESTANCIAID, $CUENTAAGTN, $CUENTASQLSER, "$env:UserDomain\$env:USERNAME"
# get the current content of the file
$content = Get-Content -path $copyFileLocation -Raw
# loop over the search and replace strings to do all replacements
for ($i = 0; $i -lt $searchStrings.Count; $i++) {
$content = $content -replace [regex]::Escape($searchStrings[$i]), $replaceString[$i]
}
# finally, write the updated content to a (new) file
$content | Set-Content -Path $copyFileLocation
另一种方法是使用存储搜索字符串和替换字符串的哈希表
:
$inputFile = 'D:\Test\TheFile.txt' # your input file path here ($copyFileLocation)
$outputFile = 'D:\Test\TheReplacedFile.txt' # for safety create a new file instead of overwriting the original
$hash = @{
'"INSTANCENAME="TEST""' = $NUEVAINESTANCIA
'"INSTANCEID="TEST""' = $NUEVAINESTANCIAID
"NT Service\SQLAgent#TEST" = $CUENTAAGTN
"NT Service\MSSQL#TEST" = $CUENTASQLSER
"##MyUser##" = "$env:UserDomain\$env:USERNAME"
}
# get the current content of the file
$content = Get-Content -path $copyFileLocation -Raw
# loop over the items in the hashtable to do all replacements
$hash.GetEnumerator() | ForEach-Object {
# the `$_` is an automatic variable you get within a ForEach-Object{}
# It represents a single item on each iteration.
$content = $content -replace [regex]::Escape($_.Key), $_.Value
}
# finally, write the updated content to a (new) file
$content | Set-Content -Path $copyFileLocation
在这两种情况下,我们都使用-replace
,这是一种不区分大小写的正则表达式替换。因为您的搜索字符串包含在正则表达式中具有特殊意义的字符(
和\
),所以我们需要使用[regex]::escape()
希望对你有所帮助,这是我的尝试。它并不意味着瘦。而是要真正清楚它在做什么,同时充满功能(太多)并阻止您多次获取内容 在看到其他人的回答后,他们的代码更好。希望我的是可读的,并让您更好地了解如何使用管道和函数:)
哎呀。我错过了。我将把它变成一个函数。这里要提到的一点是,
.Replace()
是一种区分大小写的方法。OP可能没有意识到这一点,并且可能会在某些替换中遗漏该功能。
Function Replace1 {Process{$_ -replace '"INSTANCENAME="TEST""',$NUEVAINESTANCIA}}
Function Replace2 {Process{$_ -replace '"INSTANCEID="TEST""',$NUEVAINESTANCIAID}}
Function Replace3 {Process{$_ -replace "NT Service\SQLAgent#TEST", $CUENTAAGTN}}
Function Replace4 {Process{$_ -replace "NT Service\MSSQL#TEST", $CUENTASQLSER}}
Function Replace6 {Process{$_ -replace "##MyUser##", $user}}
$user = "$env:UserDomain\$env:USERNAME"
Write-Host $user
Get-Content -path $copyFileLocation | Replace1 | Replace2 | Replace3 | Replace4 | Replace5 | Replace6 | Set-Content -path $copyFileLocation