Powershell sponge equivalent in more useful?

There is a GNU program called sponge that absorbs input before writing to a file so you can do something like this: cat myFile | grep "myFilter" | sponge myFile cat myFile | grep "myFilter" | sponge myFile

Is there an equivalent powershell, so I can work with the file in place, without having to connect to a temporary file?

thanks

+6
source share
3 answers

In Powershell, prudent use of parentheses will cause the operation to complete completely before passing data to the next command in the pipeline. The default value for piping Get-Content is to trace line by line for the next command, but with parentheses it should form a complete data set (for example, load all lines) before continuing:

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

An alternative that can use less memory (I have not tested it) is to only force the execution of the Select-String results before continuing:

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

You can also assign things to a variable as an extra step. Any technique will load content into Powershell session memory, so be careful with large files.

Application: Select-String returns MatchInfo objects. Using Out-File adds superfluous extra empty 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 when writing, creating better output. Being that you come from * nix and are used for everything that returns strings (whereas Powershell returns objects), one way to force the output of a string is to pass them through foreach , which converts them:

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

You can try the following:

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

or

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

easier to keep in mind

+1
source

Two other methods come to mind - they are both the same, only one is a function that is on the command line. (I donโ€™t know sponges on unix, so I canโ€™t say that they imitate).

here is 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 this

 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 

NTN, Matt

+1
source

Source: https://habr.com/ru/post/892192/


All Articles