【问题标题】:replace several lines in a text file using powershell script使用powershell脚本替换文本文件中的几行
【发布时间】:2021-01-12 20:08:54
【问题描述】:

我最近才开始使用 PowerShell 脚本,目前我正在使用另一个程序正在修改的 .ini 文件,这就是我寻找动态方法的原因。我也试过用 .txt 文件对其进行测试,看看是否有其他结果。

我要编辑的文件是这样组织的:

[topic1]
Value1=1
Value2=3
Value3=keep
[topic2]
Value1=2
Value2=4
(... etc.)

有几个主题有不同数量的值,但是,主题 1 总是有 3 个值,主题 2 总是有 2 个值,所以我们会知道我必须替换的行数和值的名称根据主题使用 powershell。

现在我想像这样更改 topic2 的值:

    $file = 'D:\sample.ini'
    $find = 'Value1=2'
    $replace = 'Value1=3'

    (Get-Content $file).replace($find, $replace) | Set-Content $file

期望 .ini 文件看起来像这样:

[topic1]
Value1=1
Value2=3
Value3=keep
[topic2]
Value1=3
Value2=4
(... etc.)

#1 我不知道如何只关注“[topic2]”之后的 2 行。 (如果 topic1 和 topic2 的 value1 名称和值相同)

#2 我使用的代码根本没有改变任何东西,PowerShell 没有给我一个错误,它只是立即关闭。我尝试使用不同的方法来替换某些内容,但是在此过程之后 .txt 文件为空或根本没有发生任何事情。

#3 如果可能的话,一次替换几行也很不错,但我也可以在以后做。 (例如 value1=2,value2=4->value1=3,value2=2)

【问题讨论】:

  • 这不是一个答案,而是一个建议。您的目标似乎很常见:使用 PS 操作 ini。在这种情况下,只为我自己说话,我倾向于退后一步,对自己思考“为什么要重新发明轮子,难道没有人已经解决了这个问题吗?”果然,当您浏览PowerShell Gallery 时,那里有一些可以操作ini 文件的包。不知道它们是否对您有用,但它们可以节省您的时间。不如自己解决难题有趣(这显然是一种主观立场),但可能更快。
  • 感谢您的一般建议!我不知道,这肯定会帮助我。关于这件事,我正在开发一个可以访问该文件并读取信息的游戏。我想在任务调度程序和 ps 脚本的帮助下自动更改这些信息,因此,在这种情况下,我需要这个非常具体的东西才能工作。

标签: powershell shell replace


【解决方案1】:

正如 Arno van Boven 所说,已经有一些工具可以处理 ini 文件。但是,如果您想使用正则表达式并替换它们,请参阅此示例。

$tempfile = New-TemporaryFile

@'
[topic1]
Value1=1
Value2=3
Value3=keep
[topic2]
Value1=2
Value2=4
(... etc.)
'@ | Set-Content $tempfile -Encoding UTF8

(get-content $tempfile -raw) -replace '(?s)(?<=\[topic2\].+=)\d+','3' -replace '(?s)(?<=\[topic2\].+=.+=)\d+','5'

正则表达式分解

(?s) 将整个文本视为一个字符串,. 也将匹配新行。这需要Get-Content 上的-Raw 标志

(?&lt;=...)正向向后看,“匹配”必须遵循这种模式

\[..\] 斜线只是转义方括号,否则正则表达式会将其视为字符组

topic2这是该词的文字匹配

.+= .+ 将消耗所有字符,包括换行符,直到文字 = 是我们之后的值之前的最后一个字符。

\d+ 匹配 0 个或多个数字字符。这是我们要替换的值

对于第二个值,我们只需再添加一组.+= 即可跳过第一个值。

输出是

[topic1]
Value1=1
Value2=3
Value3=keep
[topic2]
Value1=3
Value2=5
(... etc.)

只需通过管道将其写入文件即可。

(get-content $tempfile -raw) -replace '(?s)(?<=\[topic2\].+=)\d+(?=\r?\n)','3' -replace '(?s)(?<=\[topic2\].+=.+=)\d+(?=\r?\n)','5' | Set-Content $tempfile -Encoding UTF8

【讨论】:

  • 非常感谢!这无疑帮助我找到了正确的方向。这些解释也确实有助于真正理解。我们正在寻找文字匹配后的“=”,这对我来说是有意义的。我只是遇到了一个问题:PS 替换之后任何“=”之后出现的值。这意味着我没有在示例中包含的第三个值也将更改为 5 以及之后的每个值。 (topic2,value1=3,value2=5,value3=5,etc.=5)
  • 如果有帮助,请考虑点击向上箭头。稍后我会看看你强调的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
  • 2018-06-01
  • 1970-01-01
  • 2020-10-30
相关资源
最近更新 更多