Powershell:你如何阅读和使用 在一个管道内写入 I/O?

发布于 2024-07-25 11:39:02 字数 830 浏览 10 评论 0原文

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

# 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(包括 out-file)在其 Begin{} 方法中而不是在 Process{} 中获取锁,因此它无法解决此特定示例。

还有其他想法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏夜暖风 2024-08-01 11:39:02

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

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

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"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文