我正在使用文本文件作为我正在开发的应用程序的后端。我首先开始将文本文件保留为人类可读的格式,但我认为没有任何意义,最好不要格式化。
我现在在后端开发过程中创建一个具有相同键但每个条目的值不同的单行哈希表。似乎合乎逻辑且易于使用。
以下是文本文件中条目的模型:
@{'bName'='1xx'; 'bTotal'='1yy'; 'bSet'='1zz'}
@{'bName'='2xx'; 'bTotal'='2yy'; 'bSet'='2zz'}
@{'bName'='3xx'; 'bTotal'='3yy'; 'bSet'='3zz'}
正如您所看到的,每个条目的键都相同,但值会有所不同。 (值的数字和重复性质纯粹是巧合的,并且为了模型而设置。实际值不是数字导向的,并且不会像示例中所见那样重复。 )
我可以通过输入以下内容来访问键和值:
$hash = Get-Content .\Desktop\Test.txt | Out-String | iex
输出:
Name Value ---- ----- bName 1xx bTotal 1yy bSet 1zz bName 2xx bTotal 2yy bSet 2zz bName 3xx bTotal 3yy bSet 3zz
我最终想要做的是收集bName
,bTotal
和bSet
的每个值,以便我可以将每个值附加到单独的WinForms ComboBox。 WinForms部分很简单,我只是在从文本文件中的每个哈希表中获取值时遇到一些问题。
我试过了:
$hash.Values | ?{$hash.Keys -contains 'bName'}
但无论管道中给出的$hash.Value
匹配如何,它都会打印出每$hash.Key
个。{/ p>
我知道$hash
是一个数组,我想我可能必须在foreach ($hash | %{})
循环中管理每次迭代,但我不太确定正确的方法。例如,当我尝试:
$hash | $_.Keys
或
$hash | $_.Values
它并不像哈希表一样对待每次迭代。
我在这里做错了什么?我是否会以复杂的方式解决这个问题,而有更简单的方法可以实现这一目标?我愿意接受各种各样的想法或建议。
作为事后的想法:当你离开并将注意力转移到别的东西时,一个明显的解决方案经常会出现这种情况,这很有趣。
我去吃午饭,我不能,为了我的生活,我开始理解为什么我没有意识到我可以很容易地做到这一点:
$hash.bName
或:
$hash.bTotal
或:
$hash.bSet
这将完全按照我的意愿行事。但是,考虑到所提供的答案,我可能会使用CSV格式的.ini文件,而不是创建一个哈希表数组。
答案 0 :(得分:1)
PowerShell内置了csv处理功能,因此在这种情况下使用它是一个不错的选择。因此,假设您将数据存储在标准csv格式的文件中,并带有标题:
"bName","bTotal","bSet"
"1xx","1yy","1zz"
"2xx","2yy","2zz"
"3xx","3yy","3zz"
然后你导入你的数据:
$data = Import-Csv $path
现在您有一个PsCustomObject
数组,csv文件中的每个标头都是该对象的属性。因此,例如,如果您想获得第二个对象的bTotal
,则可以执行以下操作:
$data[1].bTotal
2yy
答案 1 :(得分:1)
将哈希表存储在文本文件中的一种方法是INI format。
[hashtable1] bName=1xx bTotal=1yy bSet=1zz [hashtable2] bName=2xx bTotal=2yy bSet=2zz [hashtable3] bName=3xx bTotal=3yy bSet=3zz
INI文件基本上是文本形式的哈希表的哈希表。可以阅读like this:
$ht = @{}
Get-Content 'C:\path\to\hashtables.txt' | ForEach-Object {
$_.Trim()
} | Where-Object {
$_ -notmatch '^(;|$)'
} | ForEach-Object {
if ($_ -match '^\[.*\]$') {
$section = $_ -replace '\[|\]'
$ht[$section] = @{}
} else {
$key, $value = $_ -split '\s*=\s*', 2
$ht[$section][$key] = $value
}
}
并且写得像这样:
$ht.Keys | ForEach-Object {
'[{0}]' -f $_
foreach ($key in $ht[$_].Keys) {
'{0}={1}' -f $key, $ht[$_][$key]
}
} | Set-Content 'C:\path\to\hashtables.txt'
哈希表的哈希表中的单个值可以这样访问:
$ht['section']['key']
或者像这样:
$ht.section.key
另一种选择是将每个哈希表存储在单独的文件中
hashtable1.txt
:
bName=1xx bTotal=1yy bSet=1zz
hashtable2.txt
。
bName=2xx bTotal=2yy bSet=2zz
hashtable3.txt
:
bName=3xx bTotal=3yy bSet=3zz
这样您就可以通过ConvertFrom-StringData
将每个文件导入哈希表:
$ht1 = Get-Content 'C:\path\to\hashtable1.txt' | Out-String |
ConvertFrom-Stringdata
编写文件基本上与上面相同(没有ConverTo-StringData
cmdlet):
$ht1.Keys | ForEach-Object {
'{0}={1}' -f $_, $ht[$_]
} | Set-Content 'C:\path\to\hashtables1.txt'