Powershell: how do you read & write I/O within one pipeline?

折月煮酒 提交于 2019-12-10 15:31:02

问题


I'd like to be able to type quick, simple commands that manipulate files in-place. For example:

# prettify an XML file
format-xml foo | out-file foo

This won't work because the pipeline is designed to be "greedy." The downstream cmdlet acquires a Write lock to the file as soon as the upstream cmdlet processes the first line of input, which stalls the upstream cmdlet from reading the rest of the file.

There are many possible workarounds: write to temporary files, separate operations into multiple pipelines (storing intermediate results in variables), or similar. But I figure this is a really common task for which someone has developed a quick, shell-friendly shortcut.

I tried this:

function Buffer-Object 
{
    [CmdletBinding()]
    param (
        [parameter(Mandatory=$True, ValueFromPipeline=$True)]
        [psobject] $InputObject
    )

    begin { $buf = new-list psobject }
    process { $buf.Add($InputObject) }
    end { $buf }
}
format-xml foo | buffer-object | out-file foo

It works ok in some situations. Mapped to a short alias and rolled into a common distribution like PSCX, it would be "good enough" for quick interactive tasks. Unfortunately it appears that some cmdlets (including out-file) grab the lock in their Begin{} method rather than in Process{}, so it does not solve this particular example.

Other ideas?


回答1:


As far as I remember (can't test now), you can read a whole file into memory with the namespace notation:

${c:file1.txt} = ${c:file1.txt} -replace "a" "o"


来源:https://stackoverflow.com/questions/1035026/powershell-how-do-you-read-write-i-o-within-one-pipeline

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!