Powershell和Regex:如何替换命名部分中的INI名称,值对? [英] Powershell and Regex: How to replace a INI name,value pair inside a named section?

查看:91
本文介绍了Powershell和Regex:如何替换命名部分中的INI名称,值对?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用PowerShell v.2.0中的INI文件

I'm playing with INI files in PowerShell v.2.0

我想在具体部分中更改现有的 name = value 对.例如:我想为 [Sky] 部分设置 color = Blue ,而无需更改 [Home] 部分中的相同名称,值对.

I want to change a existing name=value pair inside a concrete section. By example: I want to set color=Blue for section [Sky] without change the same name,value pair inside [Home] Section.

我有正则表达式来获取要更改的完整部分(天空"):

I have the regex to get just the full section I want to change ('sky'):

[[ \t]*Sky[ \t]*\](?:\r?\n(?:[^[\r\n].*)?)*

我还有另一个表达式可以工作,但前提是Color是该部分的名字和值对.

I have also another expression that works, but only if Color is the first name,value pair of the section.

\[[ \t]*Sky[ \t]*\][.\s]*Color[ \t]*=[ \t]*(.*) 

这是示例ini文件:

[Sky]
Size=Big
Color=white

[Home]
Color=Black

PS:这是我现在用来替换ini文件中name = value的所有所有实例的代码,我想使用新表达式更新以仅替换在给定的部分中

PS: This is the code that i'm using now to replace all instances of a name=value in the ini file and i want to update with the new expression to replace only in a given section

$Name=Color
$Value=Blue

$regmatch= $("^($Name\s*=\s*)(.*)")
$regreplace=$('${1}'+$Value)

if ((Get-Content $Path) -match $regmatch)
{
    (Get-Content -Path $Path) | ForEach-Object { $_ -replace $regmatch,$regreplace } | Set-Content $Path
}


@TheMadTechnician 解决方案非常完美:) 下面是要点中的代码: ReplaceIniValue_Sample2.ps1

@TheMadTechnician solution it's perfect :) Here the code in a Gist: ReplaceIniValue_Sample2.ps1

@Matt 解决方案是另一种方法:
这是完整的代码: ReplaceIniValue_Sample1.ps1

@Matt solution is another approach:
Here is the complete code: ReplaceIniValue_Sample1.ps1

我正在寻找基于正则表达式的解决方案,但是 @mark z 提案非常有效,并且是Windows PowerShell进行API调用的一个很好的示例.这是经过一些小的调整的完整代码: ReplaceIniValue_Sample3.ps1

I'm looking for a solution based on regular expressions, but @mark z proposal works perfectly and is a great example of API calls from Windows PowerShell. Here is the complete code with a few minor adjustments: ReplaceIniValue_Sample3.ps1

推荐答案

这就是我要做的:将整个文件作为单个字符串读取,然后更改RegEx匹配,使其成为多行匹配,然后进行反向查找对于[Sky],接着捕获除'['以外的所有内容,直至您要更改的选项,在第二个捕获组中捕获等号另一侧的所有内容,然后根据需要进行替换.

Here's what I'd do: Read the whole file as a single string, then change your RegEx match so that it's a multiline match, then do a reverse lookup for [Sky] followed by capturing anything except '[' up to the option you want to change, capture everything on the other side of the equal sign in a second capture group, and replace as needed.

$Path="C:\Temp\prueba.ini"

@"
[Sky]
Size=Big
Color=White

[Home]
Color=Black
"@ | Set-content $Path

$Section="Sky"
$Name="Color"
$Value="Blue"

(Get-Content $Path) -join "`n" -replace "(?m)(?<=\[$Section\])([^\[]*$Name=)(.+?)$","`$1$Value" | Set-Content $Path

编辑:几乎忘记了必需的RegEx101链接来解释我的RegEx: https: //regex101.com/r/uC0cC3/1

Almost forgot the obligatory RegEx101 link to explain my RegEx: https://regex101.com/r/uC0cC3/1

Edit2 :出于v2兼容性将-Raw更改为-ReadCount 0.

Changed -Raw to -ReadCount 0 for v2 compatibility.

Edit3 :好的,我显然记错了.我认为-ReadCount 0-Raw相同,但事实并非如此.更新了代码以解决此问题.现在,它使用新的换行符将字符串数组连接起来,基本上将其转换为here-string,并且-replace可以按预期工作.

Ok, I evidently remembered incorrectly. I thought that -ReadCount 0 worked the same as -Raw but it does not. Updated code to fix this. Now it joins the array of strings with new line characters basically turning it into a here-string and now the -replace works as expected.

这篇关于Powershell和Regex:如何替换命名部分中的INI名称,值对?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆