使用PowerShell中的正则表达式替换文本文件内容

71

我有一个简单的文本文件,需要编写一个PowerShell脚本来替换文件内容中的某些部分。

我的当前脚本如下:

$content = Get-Content -path "Input.json"

$content -Replace '"(\d+),(\d{1,})"', '$1.$2' |  Out-File "output.json"

是否可能不使用content变量将其写在一行中,就像这样?

Get-Content -path "Input.json" | ??? -Replace '"(\d+),(\d{1,})"', '$1.$2' |  Out-File "output.json"

在第二个命令中,我如何在不使用$content变量的情况下使用第一个get-content命令的输出?是否存在自动powershell变量?

在管道中是否可以进行多个替换操作?

Get-Content -path "Input.json" | ??? -Replace '"(\d+),(\d{1,})"', '$1.$2' | ??? -Replace 'second regex', 'second replacement' |  Out-File "output.json"
2个回答

107

是的,你可以在一行代码中完成这个任务,甚至不需要使用管道符号,因为-replace会像你期望的那样在数组上起作用(并且你可以链接这个运算符):

(Get-Content Input.json) `
    -replace '"(\d+),(\d{1,})"', '$1.$2' `
    -replace 'second regex', 'second replacement' |
  Out-File output.json

Get-Content调用周围加上括号是必要的,以防止-replace运算符被解释为Get-Content的参数。


虽然它只能逐行工作,"\n", "b" -replace('\n', 'a')将返回 'a', 'b'。"`n", "b" -replace('\nb', 'a') 仍将返回 "\n", "b"。 - Nate Anderson
3
你可以使用Get-Content -Raw一次性处理所有行,这样你就会得到一个单一的字符串返回。 - Joey
1
@TheRedPea:嗯,你说的还是对的,因为答案中概述的方法不适用于某些替换,即需要正则表达式查看后续行的替换,因为每行都在单个字符串中,并且通过“-replace”单独运行。 - Joey
3
这会影响输出文件的编码,并在文件上放置字节顺序标记。我这样做是为了让它输出UTF-8而不带bom:$tmp = (Get-Content Input.json) -replace '"(\d+),(\d{1,})"', '$1.$2'; [System.IO.File]::WriteAllLines('output.json', $tmp)(也许你需要在输出文件名上提供完整路径)。 - Rory
2
Set-Content -Path 'output.json' 也可以输出没有字节顺序标记的文本。 - Erik Barke
显示剩余5条评论

16

不使用content变量,可以将其写在一行上吗?像这样:

是的:使用ForEach-Object(或其别名%),然后使用$_引用管道上的对象:

Get-Content -path "Input.json" | % { $_ -Replace '"(\d+),(\d{1,})"', '$1.$2' } |  Out-File "output.json"

在管道中可以进行多个替换吗?

可以。

  1. 如上所述:只需添加更多的 Foreach-Object 段落。
  2. 由于 -replace 返回结果,它们可以在单个表达式中链接:

    ($_ -replace $a,$b) -replace $c,$d
    

    我怀疑括号不是必需的,但我认为它们使阅读更容易:特别是如果匹配/替换不平凡,那么使用多个链接操作符可能并不清晰。


2
你的解决方案只有在Get-Content命令周围加上括号时才能正常工作。(Get-Content -path $inputFile) | % { $_ -Replace '"(\d+),(\d{1,})"', '$1.$2' -Replace '"(\d+)"', '$1' -Replace '_', ''} | Out-File $outputFile - Jan Baer
6
只有当"$InputFile"和"$OutputFile"相同时,才需要使用括号。 - Richard
1
你有没有任何关于为什么圆括号使得向输入文件写入成为可能的参考资料?这正是我需要的用例,但我发现它并不明显。 - Chris F Carroll
3
因为它会导致整个文件先被读入,否则文件将逐行读取和处理,并且当您尝试写入第一行时,文件仍然保持着可读状态。 - Richard
当输入文件和输出文件相同时,该解决方案不起作用。然后文件内容会被删除。当我有一个不同的输出文件时,它可以正常工作。 - Beauty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接