将文件内容传递到PowerShell命令,而不将整个文件加载到内存中


6

我最近开始使用PowerShell,希望永远不要错过 巴什 再次。

我想恢复一个实例 PostgreSQL的 数据库。在Bash或旧的命令提示符中,我会输入:

psql --username = ... db_name< backup.sql

在PowerShell中,我发现我需要这样:

Get-Content backup.sql | &安培; psql --username = ... db_name

问题是backup.sql很大 - 比我机器上的RAM量大。 获取内容 首先将文件读取到内存,然后再将其发送到 psql

这是个问题。

我怎样才能模拟出的行为 < 在PowerShell?


5.0 - Windows 10附带的版本。
zmbq

这太可怕了。 Powershell不支持并发读取和推入管道吗?
zmbq

虽然这个问题绝对是主题,但我认为你会在stackoverflow上收到更多答案
nixda

1
powershell管道与常规控制台应用程序stdin不同。我不知道细节,但也许两个不​​能像人们希望的那样很好地相互合作。 backup.sql文件的内容是什么?我想知道它是否可以分解为可以输入psql的单个sql语句。另一个想法:它在cmd.exe中有效吗?
dangph

1
它适用于旧的命令提示符,这就是我最终使用的。
zmbq

Answers:


4

好像是PowerShell Get-Content 对于大文件来说效率不高,所以你可以使用 -ReadCount 切换到告诉它一次从文件中管道的数量。我把500放在下面所以它一次管道500行。

另请阅读下面的Microsoft PowerShell文章。

PowerShell v 5.0示例

  • Get-Content -ReadCount 500 backup.sql | & psql --username=... db_name

PowerShell旧版本示例

  • Get-Content -Read 500 backup.sql | & psql --username=... db_name

自PowerShell以来 Get-Content 用大文件效率不高,看看 Start-Process

另请阅读下面的Microsoft PowerShell文章。

PowerShell v 5.0示例(使用 -RedirectStandardInput 开关)

Start-Process "C:\Program Files\PostgreSQL\<version>\bin\psql.exe" '--username=... db_name' -RedirectStandardInput backup.sql -NoNewWindow -Wait

1
不幸的是,这导致了非常奇怪的行为。内存使用量上下跳动,计算机变得非常迟缓(这是一款全新的四核代码i7,内存为16GB)。
zmbq

@zmbq我想不幸的是你可能需要查看除Get-Content之外的其他选项,因为这似乎是我认为性能低下的根本原因,因为文件太大以及它读入内存的方式等等。如果psql处理 < 比PowerShell更好,您应该能够利用它并仍然使用PowerShell和-RedirectStandardInput开关。
Pimp Juice IT

1

我如何模拟&lt;的行为?在PowerShell?

检查我对这个问题的回答: PowerShell管道添加换行符

这是我的 Invoke-RawPipeline 功能(从中获取最新版本) 这个   要旨)

用它来处理进程的标准输出和。之间的二进制数据   标准输入流。 它可以从文件/管道读取输入流   并将结果输出流保存到文件。

这个需要 PsAsync模块 能够   在多个进程中启动和管道数据。


0

为解决此问题,我使用可执行参数创建了一个powershell cmd.exe进程

$cmdArgs = @('/c','psql.exe','--username=...', .. , 'dbname' , '<', 'backup.sql' )
&'cmd.exe' $cmdArgs

完美地完成了我想要做的事情

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.