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