我有一个代码如下:
$datearray = @()
$temp = Get-Content "C:\temp.txt"
$temp1 = Get-Content "C:\temp1.txt"
foreach ($te in $temp) {
$t = $te -split '-'
$da = $t[1]
$mo = $t[2]
$yea = $t[3]
$fulldate = "$da-$mo-$yea"
if ($temp1 -match $fulldate) {
if ($fulldate -match $te) {
$datearray += $_
$fmt = 'dd-MM-yy-HH-mm'
$culture = [Globalization.CultureInfo]::InvariantCulture
*!* $datearray | sort { [DateTime]::ParseExact(($_ -split '-', 2)[1], $fmt, $culture) } | select -Last 1 | Add-Content "c:\temp4.txt"
} else {
#some operation
}
} else {
#some operation
}
}
为了您的理解,我将向您展示temp1.txt
的样子:
17-07-15
18-07-15
19-07-15
20-07-15
21-07-15
22-07-15
23-07-15
temp.txt
是:
testdatabase-17-07-15-22-00
testdatabase-17-07-15-23-00
testdatabase-21-07-15-10-00
testdatabase-21-07-15-23-00
我要做的是,每当它到达标有*!*
的代码时,每次都会返回顶部的foreach
循环。标记的代码没有被执行。
有人可以告诉我解决方案吗?
答案 0 :(得分:2)
使用Group-Object
cmdlet按日期对数据库进行分组,然后从每个组中选择最新的数据库名称:
$fmt = 'dd-MM-yy-HH-mm'
$culture = [Globalization.CultureInfo]::InvariantCulture
Get-Content 'C:\temp.txt' |
select @{n='Timestamp';e={[DateTime]::ParseExact(($_ -split '-', 2)[1], $fmt, $culture)}},
@{n='Database';e={$_}} |
group { $_.Timestamp.Date } |
% { $_.Group | sort Timestamp | select -Last 1 -Expand Database }
代码使用select
语句将行列表转换为具有Timestamp
和Database
属性的自定义对象列表,以简化数据库名称的分组和排序按日期。
在管道的每个步骤之后检查输出应该有助于您理解这背后的逻辑。 Get-Content
生成一个字符串列表,其中包含文件中的行:
PS C:\> Get-Content 'C:\temp.txt'
testdatabase-17-07-15-22-00
testdatabase-17-07-15-23-00
testdatabase-21-07-15-10-00
testdatabase-21-07-15-23-00
通过将Select-Object
与calculated properties一起使用,字符串列表将转换为具有2个属性的自定义对象列表,即数据库名称和时间戳(作为DateTime
对象):< / p>
PS C:\> Get-Content 'C:\temp.txt' |
>> select @{n='Timestamp';e={[DateTime]::ParseExact(($_ -split '-', 2)[1], $fmt, $culture)}},
>> @{n='Database';e={$_}}
>>
Timestamp Database
--------- --------
17.07.2015 22:00:00 testdatabase-17-07-15-22-00
17.07.2015 23:00:00 testdatabase-17-07-15-23-00
21.07.2015 10:00:00 testdatabase-21-07-15-10-00
21.07.2015 23:00:00 testdatabase-21-07-15-23-00
按时间戳的日期部分对这些对象进行分组,可以获得GroupInfo
个对象的列表,其Group
属性包含给定日期的数据库名称列表:
PS C:\> Get-Content 'C:\temp.txt' |
>> select @{n='Timestamp';e={[DateTime]::ParseExact(($_ -split '-', 2)[1], $fmt, $culture)}},
>> @{n='Database';e={$_}} |
>> group { $_.Timestamp.Date }
>>
Count Name Group
----- ---- -----
2 17.07.2015 00:00:00 {@{Timestamp=17.07.2015 22:00:00; Database=testdatabase-17-07-15-22-00}, @{Timestamp...
2 21.07.2015 00:00:00 {@{Timestamp=21.07.2015 10:00:00; Database=testdatabase-21-07-15-10-00}, @{Timestamp...
ForEach-Object
循环然后按时间戳对每个组的元素进行排序,并从每个组中选择最后一个(最新的)数据库名称:
PS C:\> Get-Content 'C:\temp.txt' |
>> select @{n='Timestamp';e={[DateTime]::ParseExact(($_ -split '-', 2)[1], $fmt, $culture)}},
>> @{n='Database';e={$_}} |
>> group { $_.Timestamp.Date } |
>> % { $_.Group | sort Timestamp | select -Last 1 -Expand Database }
>>
testdatabase-17-07-15-23-00
testdatabase-21-07-15-23-00