Powershell相当于moreutils中的海绵?

时间:2011-07-07 01:22:44

标签: powershell

有一个名为 sponge 的GNU程序在写入文件之前会吸收输入,因此您可以执行以下操作:cat myFile | grep "myFilter" | sponge myFile

是否有PowerShell等价物,所以我可以处理一个文件,而不必管道到临时文件?

由于

3 个答案:

答案 0 :(得分:5)

在Powershell中,明智地使用括号将强制操作在将数据传递到管道中的下一个命令之前完全完成。管道Get-Content的默认值是逐行管道到下一个命令,但是在括号中它必须形成一个完整的数据集(例如,加载所有行),然后继续:

(Get-Content myFile) | Select-String 'MyFilter' | Set-Content myFile

可能使用较少内存的替代方法(我没有对其进行基准测试)只是在继续之前强制完成Select-String的结果:

(Get-Content myFile | Select-String 'MyFilter') | Set-Content myFile

您还可以将事物分配给变量作为附加步骤。任何技术都会将内容加载到Powershell会话的内存中,所以要小心大文件。

附录: Select-String返回MatchInfo个对象。使用Out-File添加讨厌的额外空白行,因为它尝试将结果格式化为字符串,但Set-Content在写入时正确地将每个对象转换为自己的字符串,从而产生更好的输出。因为你来自* nix并且习惯于所有返回字符串的东西(而Powershell返回对象),强制字符串输出的一种方法是通过转换它们的foreach来管道它们:

(Get-Content myFile | Select-String 'MyFilter' | foreach { $_.tostring() }) | Set-Content myFile

答案 1 :(得分:1)

你可以试试这个:

(Get-content myfile) | where {$_ -match "regular-expression"} | Set-content myfile

${full-path-file-name-of-myfile} | where {$_ -match "regular-expression"} | add-content Anotherfile

更容易记住

答案 2 :(得分:1)

另外两种方式可以想到 - 它们都是相同的,实际上只有一种是另一种功能,另一种是在命令行上。 (我不知道unix上的海绵,所以我不能肯定地说它们模仿它。)

这是命令行中的第一个

Get-Content .\temp.txt | 
    Select-String "grep" | 
    foreach-object -begin { [array] $out  = @()} -process { $out = $out + ($_.tostring())} -end {write-output $out}

,第二个是创建一个函数来做到这一点

function sponge {
    [cmdletbinding()]
    Param(
        [Parameter(
            Mandatory = $True,
            ValueFromPipeline = $True)]
        [string]$Output
    )
    Begin {
        [array] $out = @()
    }
    Process {
        $out = $out + $Output
    }
    End {
        Write-Output $Out
    }
}


Get-Content .\temp2.txt | Select-String "grep" | sponge

HTH, 马特