从 powershell 读取文件中的数据

Read data in file from powershell

提问人:SqlData 提问时间:10/25/2023 更新时间:10/25/2023 访问量:49

问:

我有一个文件,其中包含以此模式显示的数据。

[hashtable[]]$Counties = 
@(
@{"County1" = @{"City"="New York"
                "State"="NY"
                }
},
@{"County2" = @{"City"="Miami"
                "State"="FL"
                }
},
@{"County3" = @{"City"="Orlando"
                "State"="FL"
                }
}
)

我的目标是读取包含此数据的文件,并循环每个县(county1、county2 等),并读取每个县的城市和州。

我正在努力编写一个执行此操作的 PowerShell 脚本。任何帮助将不胜感激。

预期输出

Name    City     State
County1 New York NY
County2 Miami FL
County3 Orlando FL
PowerShell 哈希表

评论

2赞 Olaf 10/25/2023
Import-PowerShellDataFile 不应该完成这项工作吗?...或者至少是其中的很大一部分......🤷🏼‍♂️😉
1赞 Santiago Squarzon 10/25/2023
当你说你有一个包含该数据的文件时,你为什么要使用这种格式?为什么不将您的数据存储为 Json 呢?对于特定的事情,您是否需要这种方式?

答:

2赞 Santiago Squarzon 10/25/2023 #1

我建议你应该把你的数据存储为JSON而不是哈希表文字,除非你有非常具体的需求来存储你的数据,就像你现在一样。JSON非常易于阅读,也易于编辑,它也被证明是一种非常强大的格式来存储和传输数据。还有一些支持 Json 格式的免费甚至开源编辑器,例如 Visual Studio Code

[
  {
    "County1": {
      "City": "New York",
      "State": "NY"
    }
  },
  {
    "County2": {
      "City": "Miami",
      "State": "FL"
    }
  },
  {
    "County3": {
      "City": "Orlando",
      "State": "FL"
    }
  }
]

如果选择此格式,则导入数据并将其转换为预期的输出将如下所示:

$Counties = Get-Content path\to\jsonfile.json -Raw | ConvertFrom-Json
foreach ($county in $Counties) {
    foreach ($property in $county.PSObject.Properties) {
        [pscustomobject]@{
            County = $property.Name
            City   = $property.Value.City
            State  = $property.Value.State
        }
    }
}

输出:

County  City     State
------  ----     -----
County1 New York NY
County2 Miami    FL
County3 Orlando  FL
1赞 iRon 10/25/2023 #2

您演示的示例是一个 PowerShell 表达式
可以简单地将值(在相等运算符的右侧)放入 PowerShell 文件中:

@'
@(
@{"County1" = @{"City"="New York"
                "State"="NY"
                }
},
@{"County2" = @{"City"="Miami"
                "State"="FL"
                }
},
@{"County3" = @{"City"="Orlando"
                "State"="FL"
                }
}
)
'@ | Set-Content .\Data.ps1

供以后通过 PowerShell 点源调用表达式来使用

脚本范围和点溯源

点源功能允许您在当前作用域(而不是脚本作用域)中运行脚本。当您运行点源脚本时,脚本中的命令就像您在命令提示符下键入它们一样运行。脚本创建的函数、变量、别名和驱动器是在您工作的作用域中创建的。脚本运行后,您可以使用创建的项并在会话中访问其值。

$Countries = . .\Data.ps1
$Countries

Name                           Value
----                           -----
County1                        {[City, New York], [State, NY]}
County2                        {[City, Miami], [State, FL]}
County3                        {[City, Orlando], [State, FL]}

要在特定结构中“循环每个县(县 1、县 2 等)并读取每个县的城市和州”,您需要:

  • 遍历数组
    • 枚举哈希表的键和/或值
      • 枚举国家/地区表的键和/或值
$Countries | Foreach-Object {
    $Properties = @{}
    $_.GetEnumerator() | Foreach-Object {
        $Properties['Country'] = $_.Name
        $_.Value.GetEnumerator() | Foreach-Object {
            $Properties[$_.Name] = $_.Value
        }
    }
    [PSCustomObject]$Properties
}

State Country City
----- ------- ----
NY    County1 New York
FL    County2 Miami
FL    County3 Orlando
  

正如 Olaf 正确注释的那样,您提供的示例接近 PowerShell 数据文件,可以使用 PowerShell ConstrainedLanguage 模式与 cmdlet 一起安全地导入该文件Import-PowerShellDataFile

Import-PowerShellDataFile

该 cmdlet 从文件中定义的哈希表安全地导入键值对。可以使用文件的内容导入这些值。但是,运行文件中包含的任何代码。这可能会产生不需要的结果或执行不安全的代码。 在不调用代码的情况下导入数据。默认情况下,有 500 个密钥限制,但可以使用 SkipLimitCheck 开关绕过此限制。Import-PowerShellDataFile.PSD1Invoke-ExpressionInvoke-ExpressionImport-PowerShellDataFile

@'
@{Countries =
        @{County1 = @{
                City = 'New York'
                State = 'NY'
            }},
        @{County2 = @{
                City = 'Miami'
                State = 'FL'
            }},
        @{County3 = @{
                City = 'Orlando'
                State = 'FL'
            }}}
'@ | Set-Content .\Data.psd1
$Data = Import-PowerShellDataFile .\data.psd1
$Data.Countries # | Foreach-Object { ...

笔记