将文件内容通过管道传输到 PowerShell 命令中,而无需将整个文件加载到内存中

将文件内容通过管道传输到 PowerShell 命令中,而无需将整个文件加载到内存中

我最近开始使用 PowerShell,希望永远不会错过猛击再次。

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

psql --用户名=... db_name < 备份.sql

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

获取内容备份.sql | & psql --username = ... db_name

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

这是个问题。

我如何模拟<PowerShell 中的行为?

答案1

PowerShellGet-Content在处理大文件时效率较低。使用参数-ReadCount定义行处理的批处理大小可提高其性能。在下面的示例中,它被设置为500每批行的值以提高效率。阅读更多关于获取内容

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

或者,考虑探索Start-Process命令

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

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

答案2

如何在 PowerShell 中模拟 < 的行为?

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

这是我的Invoke-RawPipeline功能(从获取最新版本 此要点)

使用它在进程的标准输出和标准输入流之间传输二进制数据。它可以从文件/管道读取输入流并将得到的输出流保存到文件中。

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

答案3

为了解决这个问题,我创建了一个带有可执行参数的 powershell cmd.exe 进程

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

非常适合我想要做的事情

相关内容