PowerShell эквивалентно губке в moreutils? - PullRequest
6 голосов
/ 07 июля 2011

Существует программа GNU под названием sponge , которая впитывает ввод перед записью в файл, поэтому вы можете сделать что-то вроде этого: cat myFile | grep "myFilter" | sponge myFile

Есть ли эквивалент PowerShell, чтобы я мог работать с файлом на месте, без необходимости передавать его во временный файл?

Спасибо

Ответы [ 3 ]

5 голосов
/ 07 июля 2011

В 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 голос
/ 07 июля 2011

на ум приходят два других способа - оба они на самом деле одинаковы, просто один является функцией другого в командной строке.(Я не знаю sponge в unix, поэтому не могу с уверенностью сказать, что они имитируют его)функция для этого

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

1 голос
/ 07 июля 2011

Вы можете попробовать это:

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

или

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

проще помнить

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...