如何仅管道在PowerShell中替换的行?

时间:2012-06-12 17:06:04

标签: powershell

我有这个:

(gc "$env:a.txt") -replace 'aaa', 'bbb'

我想管它,所以它会打印更改后的行(更改后),只打印它们(当然不需要简单地搜索'bbb')。怎么样?

编辑:

我忘了提到我想在这个过程中更改文件,这使得它更难(但我希望看到,作为“理智反馈”,只有更新的行):

(gc "a.txt") -replace 'aaa', 'bbb' | something-here-?? | sc a.txt

我是否必须分两步完成,或者有办法将它们全部管好?

4 个答案:

答案 0 :(得分:2)

您可以先匹配要替换的文本,然后逐行替换...

(gc a.txt) -match 'aaa' | % { $_ -replace 'aaa', 'bbb' }

我还想指出,你的代码和我的代码实际上并没有修改原始文件。

答案 1 :(得分:2)

根据您的需要,要显示正在更改的内容并替换文件内容,您可以执行以下操作:

gc test.txt | %{ 
    if($_ -match "this") {
        $replaced = $_ -replace "this","that"
        write-host $replaced
        $replaced
    } else{
        $_
    }

} | sc test2.txt

如果您只是想在替换后看到差异,可以使用compare-object

答案 2 :(得分:1)

我没有看到任何理由不使用seth的方法但是如果有一些微妙的东西,或者如果你只是喜欢打字:有一个内置的差异。为了改变改变的行的变化:

  diff (gc myfile) ((gc myfile) -replace "x", "y")) |  % { if ($_.SideIndicator -eq '=>') { $_.InputObject } }

(你可以通过删除SideIndicator的测试获得orig和更改)

答案 3 :(得分:1)

您可以使用ForEach-Object检查新值的每个替换值并将其写出。只需确保继续将所有内容传递到管道中:

(Get-Content "a.txt") -replace 'aaa', 'bbb' | 
    ForEach-Object { if( $_ -like '*bbb*' ) { Write-Host $_ } $_ } | 
    Set-Content a.txt

它将显示已包含bbb的任何行。如果你真的只想在之前和之后看到:

Get-Content "a.txt" | 
    ForEach-Object {
         if( $_ -match 'aaa' ) 
         {
             $newLine = $_ -replace 'aaa','bbb'
             Write-Host "> $_"
             Write-Host "< $newLine"
             $newLine
         }
         else
         {
             $_
         }

    } |
    Set-Content a.txt