powershell和从非结构化文本到hashtab的字符串

时间:2014-01-21 19:23:32

标签: parsing powershell hashtable

我尝试找到从这些输出中找到两个变量的最佳解决方案:

Backup   server1_incr       Completed  incr  1/15/2014 6:00:06 PM     0:00     0:04   0.84 1 0  0  19672 100% 2014/01/15-10
Backup   server2_incr       Completed  incr  1/15/2014 6:00:06 PM     0:00     0:04   0.84 1 0  0  19672 100% 2014/01/15-10
Backup   vea server3_d4d    Completed  incr  1/15/2014 6:00:06 PM     0:00     0:04   0.84 1 0  0  19672 100% 2014/01/15-10
Backup   ae server4011_d2d  Completed  incr  1/15/2014 6:00:06 PM     0:00     0:04   0.84 1 0  0  19672 100% 2014/01/15-10
Backup   server6_incr       Completed  incr  1/15/2014 6:00:06 PM     0:00     0:04   0.84 1 0  0  19672 100% 2014/01/15-9

我需要从每一行只有两个项目 - 从2列(server1_incr; ae server4011_d2d ...)到最后一列(2014/01 / 15-10; 2014/01 / 15-9)结束。 在解析行字符串之后,将值存储在hashtab中以进行另一次处理:

    key                 value
server1_incr        2014/01/15-10
server2_incr        2014/01/15-10
ae server4011_d2d   2014/01/15-10

有什么想法吗?我睡了2个晚上没有睡觉,也没有想法。感谢

一个小时的睡觉是个好主意:)现在更多的分钟,我有代码 - 我知道,不好......但是对于基地......

$srvIDht = @{}

$inputData = Get-Content "c:\scripts\DPout"
foreach ($line in $inputData) {
$inline = $line

([regex]::match($inline,"(?<=Backup)[^/]+(?=Completed)").Value).ToString().Trim() | foreach { $srv = ($_) }
([regex]::match($inline,"(?<=%\s).*").Value).ToString().Trim() | foreach { $bID = ($_) }

$srvIDht.$srv += @( "$bID" )
} 

2 个答案:

答案 0 :(得分:2)

这是一个使用正则表达式的版本,并保持哈希表与输入的顺序相同。如果您未使用至少版本3的powershell,请删除第一行,并从第三行删除[ordered]标记:

#requires -version 3.0

$lines = get-content "F:\scripts\text2ht\datafile"
$hashTable = [ordered]@{}

foreach ( $line in $lines ) {
    if ($line -cmatch '^Backup\s+(.+?)\s+Completed.*%\s+(.*?)$') {
        $key = $matches[1]
        $value = $matches[2]
        $hashTable.Add( $key, $value )
    }
}
$hashTable

这看起来非常像omnirpt的输出(尽管我的服务器上的间距不同)。如果您想要捕获SessionID,即使备份未成功完成,您也可以将cmatch更改为:

'^Backup\s+(.+?)\s+(?:Completed|Failed|In Progress).*%\s+?(.*?)\s*$'

在我的测试用例中,它捕获了已完成,已完成/错误,失败和正在进行的状态。

答案 1 :(得分:1)

如果文字在文件C:\Temp\data.txt中,您可以尝试:

$a = Get-Content C:\Temp\data.txt
$b = $a | % {@{$($_.substring(9,18))=$($_.substring(110,13))}}
$b
Name                           Value
----                           -----
server1_incr                   2014/01/15-10
server2_incr                   2014/01/15-10
vea server3_d4d                2014/01/15-10
ae server4011_d2d              2014/01/15-10
server6_incr                   2014/01/15-9

您可以修剪键和值。