Powershell:使用 key = value 更新属性文件

Powershell : Update properties file with key = value

我的要求是,我有一个 属性文件 说 C:\google\configuration\backup\configuration.properties 内容如下

backup.path = C:\ProgramData\google\backup
backup.volume.guid = \\?\Volume{49e5d325-8065-49f4-bf0d-r4be94cc1feb}\
backup.max.count = 10

我有一个将键和值作为输入的方法。

function Script:change_or_replace_value([string]$key, [string]$value) {

    $origional_file_content = Get-Content $CONF_FILE_LOCATION
    $key_value_map = ConvertFrom-StringData($origional_file_content -join [Environment]::NewLine)
    $old_value = $key_value_map.$key
    $Old_file_pattern = "$key = $old_value"
    $new_file_pattern = "$key = $value"

    $origional_file_content | ForEach-Object {$_ -Replace $Old_file_pattern, $new_file_pattern} | Set-Content $NEW_FILE_LOCATION

}
  1. 如果键为“backup.volume.guid”且值为“\\?\Volume{111111-222-222-444-r4be94cc1feb}\” 方法应该替换文本
backup.path = C:\ProgramData\google\backup
backup.volume.guid = \\?\Volume{111111-222-222-444-r4be94cc1feb}\
backup.max.count = 10
  1. 如果键为“backup.volume.guid”且值为“”,方法应删除行
backup.path = C:\ProgramData\google\backup
backup.max.count = 10

如果值为空,则删除该行,否则替换给定键的文本。

您当前的方法有两个问题,基于您尝试通过 字符串操作 文件内容更新为单个字符串 :

  • ForEach-Object 脚本块中,您需要一个不同的命令来 消除 一行,因为 运算符 总是 returns 某事:如果正则表达式模式与输入不匹配,则输入字符串通过

  • 您缺少一个额外的字符串替换步骤:ConvertFrom-StringData\ 视为转义字符,因此输入文件中的任何一对 \ 都会变成到结果哈希表中的单个 \ 中。因此,您还必须将 $oldvalue$value 中的 \ 加倍,以便对原始文件内容进行字符串替换。

  • 此外,-replace,因为它期望 regex (regular expression) 作为搜索操作数,所以需要 \ 等元字符 转义 通过 \-转义它们;你可以用 [regex]::Escape($Old_file_pattern).


建议一种不同的方法来避免这些问题,即:

  • 直接修改ConvertFrom-StringDatareturns.

    的hashtable
  • 然后使用字符串格式将更新的哈希表序列化到输出文件。

    • 作为字符串格式的一部分,使用 [string] 类型的 .Replace() 方法再次将值中的 \ 加倍,该方法对 literal 字符串,在这种情况下更简单(也更快);但是,您也可以使用有点违反直觉的 -replace '\', '\'
# Assign your real path here.
$OCUM_CONF_FILE_LOCATION = 'in.properties'

# Only for demonstration here: create a sample input file.
@'
backup.path = C:\ProgramData\google\backup
backup.volume.guid = \\?\Volume{49e5d325-8065-49f4-bf0d-r4be94cc1feb}\
backup.max.count = 10
'@ > $OCUM_CONF_FILE_LOCATION

# Function which either updates, adds, or removes an entry.
# NOTE: 
#   * This function updates input file $OCUM_CONF_FILE_LOCATION *in place*.
#     To be safe, be sure to have a backup copy before you try this.
#   * Set-Content's default character encoding is used to save the updated file.
#     Use the -Encoding parameter as needed.
function Update-PropertiesFile ([string]$key, [string]$value) {
  $ht = ConvertFrom-StringData (Get-Content -Raw $OCUM_CONF_FILE_LOCATION)
  if ($ht.Contains($key)) { # update or delete existing entry
    if ('' -eq $value) { $ht.Remove($key) }
    else               { $ht[$key] = $value }
  } elseif ('' -eq $value) { # entry to remove not found
    Write-Warning "No entry with key '$key' found; nothing to remove."
    return
  } else { # new entry 
    $ht[$key] = $value
  }
  # Serialize the updated hashtable back to the input file.
  Set-Content $OCUM_CONF_FILE_LOCATION -Value $( 
    foreach ($key in $ht.Keys) {
     '{0} = {1}' -f $key, $ht[$key].Replace('\', '\')
    }
  )
}