我是Powershell脚本的新手,并且已经阅读了Powershell教程以完成当前的脚本要求。
我正在尝试通过匹配模式在行中添加感叹号。我有如下类似的test.default文件
"/AgentSetup/__type__"
"/AgentSetup/__name__"
"/AgentSetup/preloadedKs"
"/AgentSetup/preloadedKMsArch"
"/AgentSetup/loadOnlyPreloadedKMs"
文件中有更多类似的行
所以在这里,我尝试通过匹配来在行的开头添加感叹号,例如,如果我搜索“ / AgentSetup / preloadedKs” = {REPLACE =“”},那么在文件中它应该看起来像
"/AgentSetup/__type__"
"/AgentSetup/__name__"
"/AgentSetup/preloadedKs"
!"/AgentSetup/defaultAccount"
"/AgentSetup/preloadedKMsArch"
"/AgentSetup/loadOnlyPreloadedKMs"
我尝试使用以下命令来实现此目的,但没有成功
$TEST = "C:\Asset\config.default"
$Pattern = "/AgentSetup/defaultAccount"
$var = "!" + (Select-String -Path $TEST -pattern $Pattern | Out-String)
$var
$var + (Get-Content $TEST -Raw) | Set-Content $TEST
以上命令不仅在文件中添加了感叹号,还添加了这样的文件:
!
test.default:103:"/AgentSetup/defaultAccount"
即使我搜索了Add-Content
,我也已经阅读过Powershell Select-String
和Get-Content
教程。请引导我朝正确的方向,这样我才能实现这一目标。
答案 0 :(得分:1)
您的方法有两个问题:
正如Mathias R. Jessen在评论中建议的那样,与其将Select-String
调用的输出传递到Out-String
[1] ,不如访问{{1 }}属性中的结果,其中仅包含匹配的行。
.Line
不输出字符串 ,而是输出其 Select-String
属性的match-information objects 包含匹配的行(字符串)。
请注意,有一个呈绿色亮起的功能建议-从Windows PowerShell Core 6.2.0开始尚未实现-使用建议的.Line
开关允许Select-String
直接发出字符串-参见https://github.com/PowerShell/PowerShell/issues/7713
您只是将感兴趣的行的修改后的副本添加到输出中,这意味着未经修改的原始行仍然是重写文件的一部分 >。
我建议完全基于-Raw
运算符使用另一种方法,这将使解决方案既简洁又快捷:
-replace
(Get-Content $TEST) -replace '^"/AgentSetup/preloadedKs"$', '!$&' | Set-Content $TEST
与每个输入字符串的开头和^
的结尾匹配,以便仅匹配除搜索字符串之外仅包含任何内容的行。
$
是匹配项的占位符,即本例中的原始行;有关$&
和这些占位符的更多信息,请参见this answer。
请注意,这会将行更新为原始位置。
在-replace
中包含Get-Content
调用可确保从头开始读取文件,从而可以在同一管道中使用(...)
写回同一文件;虽然这很方便,但是如果中断写回文件,则可能会导致数据丢失的风险。
[1] Set-Content
的目的是创建对象的字符串表示形式,因为它们会打印到控制台上,通常不适合于编程处理;在这种情况下,即使在match-info对象上使用Out-String
(或将它们放在.ToString()
内)也无法按预期工作,因为结果表示形式也包括输入文件名。 >