Powershell equivalent to sponge in moreutils?
There's a GNU program called sponge that soaks up input before writing to a file so you can do something like this: cat myFile | grep "myFilter" | sponge myFile
Is there a powershell equivalent, so I can work on a file in place, without having to pipe to a temporary file?
开发者_StackOverflow中文版Thanks
In Powershell, judicious use of parentheses will force an operation to completely finish before passing data to the next command in the pipeline. The default for piping Get-Content
is to pipe line by line to the next command, but with parentheses it must form a complete data set (e.g., load all lines) before continuing:
(Get-Content myFile) | Select-String 'MyFilter' | Set-Content myFile
An alternative that may use less memory (I have not benchmarked it) is to only force the results of Select-String
to complete before continuing:
(Get-Content myFile | Select-String 'MyFilter') | Set-Content myFile
You could also assign things to a variable as an additional step. Any technique will load the contents into the Powershell session's memory, so be careful with big files.
Addendum: Select-String
returns MatchInfo
objects. Using Out-File
adds pesky extra blank lines due to the way it tries to format the results as a string, but Set-Content
correctly converts each object to its own string as it writes, producing better output. Being that you're coming from *nix and are used to everything returning strings (whereas Powershell returns objects), one way to force string output is to pipe them through a foreach
that converts them:
(Get-Content myFile | Select-String 'MyFilter' | foreach { $_.tostring() }) | Set-Content myFile
You can try this :
(Get-content myfile) | where {$_ -match "regular-expression"} | Set-content myfile
or
${full-path-file-name-of-myfile} | where {$_ -match "regular-expression"} | add-content Anotherfile
more easier to keep in mind
two other ways come to mind - they are both the same really just one is a function the other is on the command line. (I don't know sponge on unix so I can't say for certain they mimic it).
here's the first on the command line
Get-Content .\temp.txt |
Select-String "grep" |
foreach-object -begin { [array] $out = @()} -process { $out = $out + ($_.tostring())} -end {write-output $out}
and the second is two create a function to do it
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, Matt
精彩评论