Reputation: 590
I have a code as given below:
$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
}
}
For your understanding, I will show you how temp1.txt
looks like:
17-07-15
18-07-15
19-07-15
20-07-15
21-07-15
22-07-15
23-07-15
temp.txt
is:
testdatabase-17-07-15-22-00
testdatabase-17-07-15-23-00
testdatabase-21-07-15-10-00
testdatabase-21-07-15-23-00
What I am trying to do is that whenever it reaches the code marked with *!*
, it goes back to foreach
loop in the top every time. That marked code is not getting executed.
Can someone please tell me the solution?
Upvotes: 0
Views: 67
Reputation: 200443
Use the Group-Object
cmdlet to group the databases by date, then select the most recent database name from each group:
$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 }
The code uses a select
statement to transform the list of lines into a list of custom objects with a Timestamp
and a Database
property in order to simplify grouping and sorting the database names by date.
Inspecting the output after each step of the pipeline should help you understand the logic behind this. Get-Content
produces a list of strings with the lines from the file:
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
By using Select-Object
with calculated properties the list of strings is transformed into a list of custom objects with 2 properties, the database name and the timestamp (as a DateTime
object):
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
Grouping these objects by the date portion of the timestamp gets you a list of GroupInfo
objects whose Group
property contains a list of the database names for a given date:
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...
The ForEach-Object
loop then sorts the elements of each group by timestamp and selects the last (most recent) database name from each 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 } |
>> % { $_.Group | sort Timestamp | select -Last 1 -Expand Database }
>>
testdatabase-17-07-15-23-00
testdatabase-21-07-15-23-00
Upvotes: 2