【问题标题】:For loop for PowerShellPowerShell 的 For 循环
【发布时间】:2018-12-21 13:27:15
【问题描述】:

我有一个批处理脚本,但我想为 PowerShell 制作同样的脚本

这是我的批处理脚本循环:

for /F "tokens=1" %%z in ('%MYSQL% -U postgres -l ^| findstr "beheer forms loket kcs mo alfresco"') do (
    echo Dumping database %%z
    %MYPGDUMP% -h localhost -p 5432 -U postgres -F c -b -f "% %%%z".backup %%z 
)
)

现在我需要同样的,但对于 PowerShell。到目前为止,我有这个:

$database=Set-Location 'E:\Exxellence\PostgreSQL\9.5\bin\';
.\psql --% -U postgres -l | Out-String -Stream | Select-String -Pattern "beheer"

foreach ($database in $database) {
    Set-Location 'E:\Exxellence\PostgreSQL\9.5\bin\';
    .\pg_dump --% -h localhost -p 5432 -U postgres -F c -b -f "$database.backup"
}

【问题讨论】:

  • 也许从发布您到现在为止使用 powershell 尝试过的内容开始?
  • 有这样的东西。 $database=Set-Location 'E:\Exxellence\PostgreSQL\9.5\bin\'; .\psql --% -U postgres -l |串外流 | Select-String -Pattern "beheer" ForEach ($database in $database) { Set-Location 'E:\Exxellence\PostgreSQL\9.5\bin\'; .\pg_dump --% -h localhost -p 5432 -U postgres -F c -b -f "$database.backup" }
  • 请编辑您的问题并在此处插入代码。

标签: powershell loops batch-file for-loop scripting


【解决方案1】:

我发现您的 PowerShell 代码存在一些问题:

  • Set-Location 不返回任何输出,因此变量$database 为空。

  • foreach ($database in $database)

    您正在使用相同的变量,应该将数据库列表保存为循环变量。使用不同的变量作为循环变量。此外,由于$database 为空(见上文),PowerShell 将简单地跳过循环。

  • 您需要从psql 输出中提取数据库名称,否则您将获得整行(包括有关所有者、编码等的信息)。

  • “魔术运算符”--% 阻止 PowerShell 解析命令行的其余部分,因此输出文件名中的变量 $database 不会被扩展。

  • 您没有在pg_dump 命令行中指定数据库名称。

把你的代码改成这样:

Set-Location 'E:\Exxellence\PostgreSQL\9.5\bin'
$databases = (.\psql -U postgres -l) -match '^ \S' | ForEach-Object {
    ($_ -split '\s+\|\s+')[0].Trim()
} | Where-Object {
    $_ -match '^(beheer|forms|loket|kcs|mo|alfresco)$'
}

foreach ($db in $databases) {
    .\pg_dump -h localhost -p 5432 -U postgres -F c -b -f "${db}.backup" $db
}

或者像这样:

Set-Location 'E:\Exxellence\PostgreSQL\9.5\bin'
(.\psql -U postgres -l) -match '^ \S' | ForEach-Object {
    ($_ -split '\s+\|\s+')[0].Trim()
} | Where-Object {
    $_ -match '^(beheer|forms|loket|kcs|mo|alfresco)$'
} | ForEach-Object {
    .\pg_dump -h localhost -p 5432 -U postgres -F c -b -f "${_}.backup" $_
}

它应该做你想做的事。

注意:数据库名称的过滤器假定这些名称是准确的。如果它们只是部分名称,请将行更改为 $_ -match 'beheer|forms|loket|kcs|mo|alfresco'

【讨论】:

  • 你显然比我更了解 PostgreSQL,否则我们正在从对方的输入中提炼答案。 powershell 不会尝试将参数解释为.\pg_dump 吗?
  • 感谢您的反应! .\psql 的结果什么都不是?,你的第三点正是我需要的,只有来自 psql 输出的数据库名称
  • @LotPings pg_dump 是一个外部命令,所以我不希望 PowerShell 会处理这样的简单参数。但我之前也很惊讶。 ^_^;不过,这将是我对导出的第一次尝试,如果它确实产生了错误,我会对其进行改进。
  • @AnsgarWiechers 感谢您的编辑!但输出仍然没有,也许 ($_ -split '\s+|\s+')[0].Trim() 有问题?我不知道这是做什么的:P
  • 我不知道 psql 输出,但如果 | 是字面意思,则需要用反斜杠 '\s+\|\s+' 转义,否则它是备用 OR
【解决方案2】:

您的 PowerShell 代码的第一个问题是在 foreach 循环中。试试这个:

ForEach ($database in $databases)

并更改 $databases 变量的名称(第一行)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-27
    • 2018-08-21
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    相关资源
    最近更新 更多