serverstackqns
serverstackqns

Reputation: 590

if loop not seems to be working

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

Answers (1)

Ansgar Wiechers
Ansgar Wiechers

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

Related Questions