仅使用管道替换符合条件的行中的文本

时间:2016-01-25 18:36:46

标签: powershell

我的目标是替换文本文件中特定行中的特定文本,我想使用管道来实现。

首先,我尝试编写文本替换的代码,而没有将替换设置为仅在特定行中发生的条件:

$fileName = Read-Host "Enter the full path of the file, without quotes"
(Get-Content -Path $fileName -Encoding UTF8) |
  ForEach-Object { $_ -replace "01", "January " } |
  Set-Content -Path $fileName -Encoding UTF8

似乎它有效。但是,我在管道中插入了一个IF语句:

$fileName = Read-Host "Enter the full path of the file, without quotes"
(Get-Content -Path $fileName -Encoding UTF8) |
  ForEach-Object { if ($_ -match "Month") {$_ -replace "03", "March"} } |
  Set-Content -Path $fileName -Encoding UTF8

当我运行最后一个脚本时,在该过程结束时,我得到的文件只包含与if语句匹配的行。如果我正确理解发生了什么,似乎只有匹配if语句的行被传递到管道中的下一个阶段。所以我理解为什么流程的输出,但我仍然无法想象如何解决这个问题 - 如何通过管道的所有阶段传递文件中的所有行,但仍然使文本替换只发生在符合特定条件的特定行。 你能帮我解决这个问题吗?

请注意,我不想使用临时文件,并且还记得我更喜欢使用管道的优雅方式。

2 个答案:

答案 0 :(得分:2)

您必须添加else语句,如:

(Get-Content -Path $fileName -Encoding UTF8) | 
    Foreach-Object { If ($_ - match "Month")  { $_ -replace "03", "March"} else { $_ }  } | 
    Set-Content -Path $fileName - Encoding UTF8

没有else你没有把线放进管道。因此,您的if就像过滤器一样

答案 1 :(得分:1)

根据输入数据的样子,您可能根本不需要嵌套条件(或ForEach-Object)。如果你的输入看起来像这样:

Month: 03

你可以这样替换:

(Get-Content -Path $fileName -Encoding UTF8) -replace '^(.*Month.*)03','$1March' |
  Set-Content -Path $fileName -Encoding UTF8

这将仅修改与模式匹配的行(^(.*Month.*)03)并保持其他所有内容不变。