【问题标题】:Powershell: how do you read & write I/O within one pipeline?Powershell:您如何在一个管道中读取和写入 I/O?
【发布时间】:2010-11-05 07:44:00
【问题描述】:

我希望能够输入快速、简单的命令来就地操作文件。例如:

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

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

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

我试过了:

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(包括输出文件)似乎在其 Begin{} 方法中而不是在 Process{} 中获取锁,因此它不能解决这个特定示例。

其他想法?

【问题讨论】:

    标签: powershell file-io pipeline


    【解决方案1】:

    据我记得(现在无法测试),您可以使用命名空间符号将整个文件读入内存:

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

    【讨论】:

    • 非常酷!从未见过这种语法。请注意,对于上面的具体示例,您需要在赋值的 RHS 周围使用括号: ${c:foo} = ( ${c:foo} | format-xml )。或者您可以使用修改后的管道: ${c:foo} |格式-xml |输出文件 foo
    • 这是用于访问变量的相同语法。 Providers 上有一个特殊的接口来支持这一点,但并不是所有的提供者都实现了它。这就是您在变量提供程序中访问变量的真正方式。
    猜你喜欢
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 2012-06-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    • 2019-07-20
    • 1970-01-01
    相关资源
    最近更新 更多