代码之家  ›  专栏  ›  技术社区  ›  Richard Berg

PowerShell:如何在一个管道中读写I/O?

  •  4
  • Richard Berg  · 技术社区  · 15 年前

    我希望能够输入快速,简单的命令,在适当的地方操作文件。例如:

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

    这不起作用,因为管道被设计为“贪婪的”。一旦上游cmdlet处理第一行输入,下游Cmdlet就会获取文件的写锁,从而阻止上游Cmdlet读取文件的其余部分。

    有许多可能的解决方法:写入临时文件、将操作分离到多个管道(将中间结果存储在变量中)或类似的方法。但我认为这是一个非常常见的任务,有人开发了一个快速、对外壳友好的快捷方式。

    我试过这个:

    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
    

    在某些情况下工作正常。它映射到一个短别名,并卷进一个像pscx这样的公共发行版中,对于快速交互任务来说“足够好”。不幸的是,一些Cmdlet(包括out文件)似乎在begin方法中而不是在process中获取锁,因此它无法解决这个特定的示例。

    其他想法?

    1 回复  |  直到 15 年前
        1
  •  7
  •   guillermooo    15 年前

    据我所知(现在无法测试),您可以使用名称空间表示法将整个文件读取到内存中:

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