首页 > 解决方案 > 如何使用这些值(从 .ps1 文件中读取)来更新另一个 .ps1 文件的值

问题描述

我有一个4.ps1看起来像这样的文件

#akabradabra
$one = 'o'

#bibi
$two = 't'

$three = 't'              #ok thr


#four
$four = 'four'

还有一个3.ps1看起来像这样的文件

#akabradabra
$one = 'one'

#biblibablibo
$two = 'two'

$three = 'three'              #ok threer

我的目标是从中读取键值对4.ps1并更新其中的值3.ps1,如果在 中引入了新的键值对4.ps1,只需将它们附加到3.ps1.

我的想法是使用字符串函数,例如.Split('=').Replace(' ', '')来提取键,如果键匹配,则将整行替换为3.ps14.ps1

我知道使用可能会解决问题,如果我将所有键值对转换为文件或文件Get-Variable,使用数据也会容易得多,但是谁能告诉我如何让它在我自己的工作中工作愚蠢的方式?.xml.json

这是我的代码

# Ignore this function, this is used to skip certain key-value pairs
#----------------------------------------------------------------------------
Function NoChange($something) {

    switch ($something) {

        '$CurrentPath' {return $true}
        '$pathToAdmin' {return $true}
        '$hostsPathTocompare' {return $true}
        '$logs' {return $true}
        '$LogFile' {return $true}
        default {return $false}

    }
}
#----------------------------------------------------------------------------

$ReadFromVARS = Get-Content $PSScriptRoot\4.ps1
$WriteToVARS = Get-Content $PSScriptRoot\3.ps1

foreach ($oldVar in $ReadFromVARS) {

    if (('' -eq $oldVar) -or ($oldVar -match '\s*#+\w*')) {
        continue
    } elseif ((NoChange ($oldVar.Split('=').Replace(' ', '')[0]))) {
        continue
    } else {
        $var = 0
        #$flag = $false
        while ($var -ne $WriteToVARS.Length) {
            if ($WriteToVARS[$var] -eq '') {
                $var += 1
                continue
            } elseif ($WriteToVARS[$var] -match '\s*#+\w*') {
                $var += 1
                continue
            } elseif ($oldVar.Split('=').Replace(' ', '')[0] -eq $WriteToVARS[$var].Split('=').Replace(' ', '')[0]<# -and !$flag#>) {
                $oldVar
                $WriteToVARS.replace($WriteToVARS[$var], $oldVar) | Set-Content -Path $PSScriptRoot\3.ps1 -Force
                break
                #$var += 1
                #$flag = $true
            } elseif (<#!$flag -and #>($var -eq $WriteToVARS.Length)) {
                Add-Content -Path $PSScriptRoot\3.ps1 -Value $oldVar -Force
                $var += 1
            } else {
                $var += 1
            }
        }
    }
}

我没有遇到任何错误,但它只更新了一个键值对 ( $two = t),并且最后没有附加新的键值对。这是我得到的结果

#akabradabra
$one = 'one'

#biblibablibo
$two = 't'

$three = 'three'              #ok threer

标签: regexpowershell

解决方案


如果我正确理解您的问题,我认为Dot-Sourcing就是您所追求的。

PowerShell 点源运算符将脚本文件带入当前会话范围。这是一种重用脚本的方法。脚本文件中定义的所有脚本函数和变量都成为它的源脚本的一部分。这就像将脚本文件中的文本直接复制并粘贴到您的脚本中。

要使其可见,请使用 Dot-Sourcing 从文件 3.ps1 中读取变量,显示变量及其值。下一个点源文件 4.ps1 并再次显示变量:

. 'D:\3.ps1'

Write-Host "Values taken from file 3.ps1" -ForegroundColor Yellow

"`$one   : $one"
"`$two   : $two"
"`$three : $three"
"`$four  : $four"   # does not exist yet

. 'D:\4.ps1'

Write-Host "Values after dot-sourcing file 4.ps1" -ForegroundColor Yellow

"`$one   : $one"
"`$two   : $two"
"`$three : $three"
"`$four  : $four"

结果是

Values taken from file 3.ps1
$one   : one
$two   : two
$three : three
$four  : 
Values after dot-sourcing file 4.ps1
$one   : o
$two   : t
$three : t
$four  : four

如果要将这些变量写回 ps1 脚本文件,您可以:

'one','two','three','four' | Get-Variable | ForEach-Object { 
    '${0} = "{1}"' -f $_.Name,$_.Value
} | Set-Content 'D:\5.ps1' -Force

推荐阅读