我有一个文本文件列出服务器信息,如下所示:
server1
Status: on
CPU: 4 cores
Memory: 256GB
server2
Status: off
server3
Status: on
CPU: 8 cores
Memory: 512GB
我想将其转换为CSV文件,如下所示:
Name Status CPU Memory
server1 on 4 256
server2 off
server3 on 8 512
我在网上搜索密集,但无法找到任何解决方案。如果有人能在这里给我一些答案,我真的很感激。
答案 0 :(得分:0)
此解决方案假设每行的格式一致。即,服务器名称总是在一行上,并且每个其他属性都有一个冒号,后跟属性名称和属性值之间的空格。这个答案并不假设每个服务器总是具有所有三个属性,CPU,内存和状态,如示例数据所示。
$data = @()
$intput = "D:\Working\data.txt"
$output = "D:\Working\data.csv"
# Loop over each line in the text file.
foreach ($_ in Get-Content $intput) {
# Get the index of the ':' in the line.
$index = $_.IndexOf(":")
# If the index is -1 then the line is a server name.
# Create a new object and add it to the array.
if ($index -eq -1) {
$data += New-Object -TypeName PsCustomObject -Property @{ Name = $_; Status = ""; CPU = ""; Memory = "" }
}
# If the index is not -1 then the line is a property.
# Update the property of the last object added to the array.
else {
$propertyName = $_.Substring(0, $index)
$propertyValue = $_.Substring($index + 2, $_.Length - $index - 2)
switch ($propertyName) {
"CPU" { $data[$data.Length - 1].CPU = $propertyValue }
"Memory" { $data[$data.Length - 1].Memory = $propertyValue }
"Status" { $data[$data.Length - 1].Status = $propertyValue }
}
}
}
# Export the data to a CSV file.
$data | Export-Csv $output -NoTypeInformation
答案 1 :(得分:0)
这区分了没有冒号的行(服务器名称)和带冒号的行(服务器属性),并为每个服务器构建数据集,每次到达新的服务器名称时重置。
# For each line in the text file
Get-Content d:\data.txt | Foreach {
if ($_ -notmatch ':') { # Line is a server name, reset.
if ($server) { [pscustomobject]($server) } # Output dataset (skip 1 at beginning).
$server = [ordered]@{'Name'=$_.Trim()} # create new dataset.
} else { # Line is a server property
$key, $value = $_.split(':') # Process line.
$server[$key.Trim()] = $value.Trim() # Add details to dataset.
}
} | Export-Csv D:\data.csv -NoTypeInformation # Export, without PS Type details.
编辑:上述版本仅在文件末尾有换行符时才有效。这里有一个变体,如果文件末尾没有换行符,则运行相同的逻辑,但这次使用switch
在没有冒号和行的行之间切换,并使用ForEach -End {}
阻止输出最后一个条目。
Get-Content D:\data.txt | ForEach { Switch -Regex ($_) {
':' {$key, $value = $_.Split(':'); $block[$key] = $value; break}
default {if ($block) {[pscustomobject]$block}; $block = [ordered]@{'Name'=$_ }}
}} -End {[pscustomobject]$block}
(是的,你可以把它扩展到20行而不是4行...或者在原始版本中添加-End{}
块。