1

我有这个:

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

我想以某种方式对其进行管道传输,以便打印已更改的行(更改后),并且仅打印它们('bbb'当然,不简单地搜索 ..)。如何 ?

编辑:

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

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

我必须分两步完成还是有办法将它们全部通过管道传输?

4

4 回答 4

2

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

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

我还想指出,您的代码以及源自您的代码的代码实际上并没有修改原始文件。

于 2012-06-12T17:15:16.510 回答
2

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

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

} | sc test2.txt

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

于 2012-06-12T18:34:12.413 回答
1

我看不出有任何理由不使用 seth 的方法,但如果有一些微妙的东西,或者如果你只是喜欢打字:有一个内置的差异。要获得更改的行的更改版本:

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

(您可以通过删除 SideIndicator 的测试来获得原始和更改)

于 2012-06-12T17:30:08.837 回答
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
于 2012-06-12T19:30:27.083 回答