Parsing the log file using select-String











up vote
1
down vote

favorite
1












Team,
Thanks in advance, I'm an ITPro and learning PowerShell. I've a log file which has the data in below format. I've attached the image.
I'm finding all the line which has finished transfer in it and then running foreach loop to find the line in which the date matches the current date using -eq operator



I wanted to then get the specific file name from that current line where the foreach loop is running. Example from my sample : first finished transfer line in the log matches the current date hence i wanted to get the file name which is HardwareEvents.evtx.



But I'm unable to find any method which can help me parse a file name in the current running for each line.



If i get the file name i can then delete the file using powersell cmdlet.



        $var = Select-String -Path "C:CredsAzCopyVerbose.log" -Pattern 'Finished Transfer' | `
Select-Object -Last 20 | ForEach-Object `
{
if (($_.Line).Substring(1,10) -eq (Get-Date).ToString('yyyy/MM/dd'))
{
$_.Line. // There is no method which I'm aware of need help in this if statement
}
Else {Write-Host "The date present in the azcopy verbose log is older"}
}


enter image description here










share|improve this question


















  • 2




    Please post the data to search through as text not as a picture. I think a single RegEx possibly with look arounds can filter the relevant file names with capture groups.
    – LotPings
    16 hours ago















up vote
1
down vote

favorite
1












Team,
Thanks in advance, I'm an ITPro and learning PowerShell. I've a log file which has the data in below format. I've attached the image.
I'm finding all the line which has finished transfer in it and then running foreach loop to find the line in which the date matches the current date using -eq operator



I wanted to then get the specific file name from that current line where the foreach loop is running. Example from my sample : first finished transfer line in the log matches the current date hence i wanted to get the file name which is HardwareEvents.evtx.



But I'm unable to find any method which can help me parse a file name in the current running for each line.



If i get the file name i can then delete the file using powersell cmdlet.



        $var = Select-String -Path "C:CredsAzCopyVerbose.log" -Pattern 'Finished Transfer' | `
Select-Object -Last 20 | ForEach-Object `
{
if (($_.Line).Substring(1,10) -eq (Get-Date).ToString('yyyy/MM/dd'))
{
$_.Line. // There is no method which I'm aware of need help in this if statement
}
Else {Write-Host "The date present in the azcopy verbose log is older"}
}


enter image description here










share|improve this question


















  • 2




    Please post the data to search through as text not as a picture. I think a single RegEx possibly with look arounds can filter the relevant file names with capture groups.
    – LotPings
    16 hours ago













up vote
1
down vote

favorite
1









up vote
1
down vote

favorite
1






1





Team,
Thanks in advance, I'm an ITPro and learning PowerShell. I've a log file which has the data in below format. I've attached the image.
I'm finding all the line which has finished transfer in it and then running foreach loop to find the line in which the date matches the current date using -eq operator



I wanted to then get the specific file name from that current line where the foreach loop is running. Example from my sample : first finished transfer line in the log matches the current date hence i wanted to get the file name which is HardwareEvents.evtx.



But I'm unable to find any method which can help me parse a file name in the current running for each line.



If i get the file name i can then delete the file using powersell cmdlet.



        $var = Select-String -Path "C:CredsAzCopyVerbose.log" -Pattern 'Finished Transfer' | `
Select-Object -Last 20 | ForEach-Object `
{
if (($_.Line).Substring(1,10) -eq (Get-Date).ToString('yyyy/MM/dd'))
{
$_.Line. // There is no method which I'm aware of need help in this if statement
}
Else {Write-Host "The date present in the azcopy verbose log is older"}
}


enter image description here










share|improve this question













Team,
Thanks in advance, I'm an ITPro and learning PowerShell. I've a log file which has the data in below format. I've attached the image.
I'm finding all the line which has finished transfer in it and then running foreach loop to find the line in which the date matches the current date using -eq operator



I wanted to then get the specific file name from that current line where the foreach loop is running. Example from my sample : first finished transfer line in the log matches the current date hence i wanted to get the file name which is HardwareEvents.evtx.



But I'm unable to find any method which can help me parse a file name in the current running for each line.



If i get the file name i can then delete the file using powersell cmdlet.



        $var = Select-String -Path "C:CredsAzCopyVerbose.log" -Pattern 'Finished Transfer' | `
Select-Object -Last 20 | ForEach-Object `
{
if (($_.Line).Substring(1,10) -eq (Get-Date).ToString('yyyy/MM/dd'))
{
$_.Line. // There is no method which I'm aware of need help in this if statement
}
Else {Write-Host "The date present in the azcopy verbose log is older"}
}


enter image description here







powershell






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 18 hours ago









aquib.rocks

205




205








  • 2




    Please post the data to search through as text not as a picture. I think a single RegEx possibly with look arounds can filter the relevant file names with capture groups.
    – LotPings
    16 hours ago














  • 2




    Please post the data to search through as text not as a picture. I think a single RegEx possibly with look arounds can filter the relevant file names with capture groups.
    – LotPings
    16 hours ago








2




2




Please post the data to search through as text not as a picture. I think a single RegEx possibly with look arounds can filter the relevant file names with capture groups.
– LotPings
16 hours ago




Please post the data to search through as text not as a picture. I think a single RegEx possibly with look arounds can filter the relevant file names with capture groups.
– LotPings
16 hours ago












3 Answers
3






active

oldest

votes

















up vote
1
down vote



accepted










To get the filenames from the log where the date is for today, you can use this:



$logfile = 'C:CredsAzCopyVerbose.log'
$today = Get-Date -UFormat "%Y/%m/%d"
$pattern = '^[(?<date>d{4}/d{2}/d{2}).*Finished transfer:s+(?<filename>.*)s+=>.*$'
Select-String -Path $logfile -Pattern $pattern | Select-Object -Last 20 | ForEach-Object {
$null = $_.Line -match $pattern
if ($matches['date'] -eq $today) {
Write-Host $matches['filename']
}
else {
Write-Host "The date present in the azcopy verbose log is older"
}
}


Instead of using Select-String, you can also do this which requires to match the pattern only once, so a bit cleaner in my opinion:



$logfile = 'C:CredsAzCopyVerbose.log'
$today = Get-Date -UFormat "%Y/%m/%d"
$pattern = '^[(?<date>d{4}/d{2}/d{2}).*Finished transfer:s+(?<filename>.*)s+=>.*$'
Get-Content -Path $logfile | Select-Object -Last 20 | Where-Object { $_ -match $pattern } | ForEach-Object {
if ($matches['date'] -eq $today) {
Write-Host $matches['filename']
}
else {
Write-Host "The date present in the azcopy verbose log is older"
}
}


p.s. I use Get-Date -UFormat "%Y/%m/%d" because (Get-Date).ToString('yyyy/MM/dd') on my Dutch machine outputs 2018-11-10



Regex Details



^                     Assert position at the beginning of the string
[ Match the character “[” literally
(?<date> Match the regular expression below and capture its match into backreference with name “date”
d Match a single digit 0..9
{4} Exactly 4 times
/ Match the character “/” literally
d Match a single digit 0..9
{2} Exactly 2 times
/ Match the character “/” literally
d Match a single digit 0..9
{2} Exactly 2 times
)
. Match any single character that is not a line break character
* Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
Finished transfer: Match the characters “Finished transfer:” literally
s Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
+ Between one and unlimited times, as many times as possible, giving back as needed (greedy)
(?<filename> Match the regular expression below and capture its match into backreference with name “filename”
. Match any single character that is not a line break character
* Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
)
s Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
+ Between one and unlimited times, as many times as possible, giving back as needed (greedy)
=> Match the characters “=>” literally
. Match any single character that is not a line break character
* Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
$ Assert position at the end of the string (or before the line break at the end of the string, if any)





share|improve this answer























  • First of all, Thanks Theo for teaching me a newer way to achieve this and i learnt a new thing today. Thanks once again. Only one thing i wanted to know, how did you created the regex pattern? can you please guide me through a link or the way you created this? It would be helpful. Thanks once again.
    – aquib.rocks
    15 hours ago








  • 2




    @aquib.rocks I have added the details for the regex. I always use RegexBuddy (not free..), but you can also experiment on regex101.com
    – Theo
    14 hours ago






  • 1




    you are more than awesome my friend, i was confused as to how the regex knew the file name, when you haven't written any code. but now i know through your explanation that it automatically know that anything before the => is the file name through regex. (?<filename>.*)s+=>.*$' Thanks brother for all the help.
    – aquib.rocks
    14 hours ago






  • 1




    @mklement0 Thanks for this. Yet again another way of getting the captured groups. As for escaping the /, I just didn't think of doing that.
    – Theo
    13 hours ago










  • Nice, but even with Select-String you don't have to match twice, because you can access the capture groups via $_.Matches[0].Groups, e.g., $_.Matches[0].Groups['filename'].Value. You don't have to resort to a Unix date format to ensure literal use of /; simply -escape it (or use embedded quoting): Get-Date -Format "yyyy/MM/dd"
    – mklement0
    13 hours ago




















up vote
0
down vote













Below is an approach using regex for date.



$var = Select-String -Path "C:CredsAzCopyVerbose.log" -Pattern 'Finished Transfer' | 
Select-Object -Last 20 | ForEach-Object -Process {
$_.Line -match 'd{4}/d{2}/d{2}' | Out-Null
[string]$Match = $Matches.Values
if ([Datetime]$Match -eq (Get-Date).ToString('yyyy/MM/dd'))
{
$_.Line. // There is no method which I'm aware of need help in this if statement
}
Else {Write-Host "The date present in the azcopy verbose log is older"}
}





share|improve this answer




























    up vote
    0
    down vote













    To complement Theo's helpful answer:



    It is not obvious, but it is possible to access a Select-String command's [named] capture-group matches in a ForEach-Object script block (no need to repeat matching with -match):



    PS> '... File transfer: C:pathtofile => ...' |
    Select-String 'bFile transfer: (?<file>.+?) =>' |
    ForEach-Object { $_.Matches[0].Groups['file'].Value }
    C:pathtofile # Value of named capture group 'file'



    • $_.Matches is the collection of matches for the current input line; unless -AllMatches was specified, there's only one entry, with index 0.


    • .Groups accesses the collection of capture-group matches (with the entry at index 0 containing the overall match).


    • ['file'] accesses the match for named capture group file, but note that at index-based access works equally (for unnamed capture groups), starting with index 1; that is, $_.Matches[0].Groups[1].Value in the command above would have yielded the same result.







    share|improve this answer





















      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














       

      draft saved


      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237758%2fparsing-the-log-file-using-select-string%23new-answer', 'question_page');
      }
      );

      Post as a guest
































      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      1
      down vote



      accepted










      To get the filenames from the log where the date is for today, you can use this:



      $logfile = 'C:CredsAzCopyVerbose.log'
      $today = Get-Date -UFormat "%Y/%m/%d"
      $pattern = '^[(?<date>d{4}/d{2}/d{2}).*Finished transfer:s+(?<filename>.*)s+=>.*$'
      Select-String -Path $logfile -Pattern $pattern | Select-Object -Last 20 | ForEach-Object {
      $null = $_.Line -match $pattern
      if ($matches['date'] -eq $today) {
      Write-Host $matches['filename']
      }
      else {
      Write-Host "The date present in the azcopy verbose log is older"
      }
      }


      Instead of using Select-String, you can also do this which requires to match the pattern only once, so a bit cleaner in my opinion:



      $logfile = 'C:CredsAzCopyVerbose.log'
      $today = Get-Date -UFormat "%Y/%m/%d"
      $pattern = '^[(?<date>d{4}/d{2}/d{2}).*Finished transfer:s+(?<filename>.*)s+=>.*$'
      Get-Content -Path $logfile | Select-Object -Last 20 | Where-Object { $_ -match $pattern } | ForEach-Object {
      if ($matches['date'] -eq $today) {
      Write-Host $matches['filename']
      }
      else {
      Write-Host "The date present in the azcopy verbose log is older"
      }
      }


      p.s. I use Get-Date -UFormat "%Y/%m/%d" because (Get-Date).ToString('yyyy/MM/dd') on my Dutch machine outputs 2018-11-10



      Regex Details



      ^                     Assert position at the beginning of the string
      [ Match the character “[” literally
      (?<date> Match the regular expression below and capture its match into backreference with name “date”
      d Match a single digit 0..9
      {4} Exactly 4 times
      / Match the character “/” literally
      d Match a single digit 0..9
      {2} Exactly 2 times
      / Match the character “/” literally
      d Match a single digit 0..9
      {2} Exactly 2 times
      )
      . Match any single character that is not a line break character
      * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      Finished transfer: Match the characters “Finished transfer:” literally
      s Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
      + Between one and unlimited times, as many times as possible, giving back as needed (greedy)
      (?<filename> Match the regular expression below and capture its match into backreference with name “filename”
      . Match any single character that is not a line break character
      * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      )
      s Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
      + Between one and unlimited times, as many times as possible, giving back as needed (greedy)
      => Match the characters “=>” literally
      . Match any single character that is not a line break character
      * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      $ Assert position at the end of the string (or before the line break at the end of the string, if any)





      share|improve this answer























      • First of all, Thanks Theo for teaching me a newer way to achieve this and i learnt a new thing today. Thanks once again. Only one thing i wanted to know, how did you created the regex pattern? can you please guide me through a link or the way you created this? It would be helpful. Thanks once again.
        – aquib.rocks
        15 hours ago








      • 2




        @aquib.rocks I have added the details for the regex. I always use RegexBuddy (not free..), but you can also experiment on regex101.com
        – Theo
        14 hours ago






      • 1




        you are more than awesome my friend, i was confused as to how the regex knew the file name, when you haven't written any code. but now i know through your explanation that it automatically know that anything before the => is the file name through regex. (?<filename>.*)s+=>.*$' Thanks brother for all the help.
        – aquib.rocks
        14 hours ago






      • 1




        @mklement0 Thanks for this. Yet again another way of getting the captured groups. As for escaping the /, I just didn't think of doing that.
        – Theo
        13 hours ago










      • Nice, but even with Select-String you don't have to match twice, because you can access the capture groups via $_.Matches[0].Groups, e.g., $_.Matches[0].Groups['filename'].Value. You don't have to resort to a Unix date format to ensure literal use of /; simply -escape it (or use embedded quoting): Get-Date -Format "yyyy/MM/dd"
        – mklement0
        13 hours ago

















      up vote
      1
      down vote



      accepted










      To get the filenames from the log where the date is for today, you can use this:



      $logfile = 'C:CredsAzCopyVerbose.log'
      $today = Get-Date -UFormat "%Y/%m/%d"
      $pattern = '^[(?<date>d{4}/d{2}/d{2}).*Finished transfer:s+(?<filename>.*)s+=>.*$'
      Select-String -Path $logfile -Pattern $pattern | Select-Object -Last 20 | ForEach-Object {
      $null = $_.Line -match $pattern
      if ($matches['date'] -eq $today) {
      Write-Host $matches['filename']
      }
      else {
      Write-Host "The date present in the azcopy verbose log is older"
      }
      }


      Instead of using Select-String, you can also do this which requires to match the pattern only once, so a bit cleaner in my opinion:



      $logfile = 'C:CredsAzCopyVerbose.log'
      $today = Get-Date -UFormat "%Y/%m/%d"
      $pattern = '^[(?<date>d{4}/d{2}/d{2}).*Finished transfer:s+(?<filename>.*)s+=>.*$'
      Get-Content -Path $logfile | Select-Object -Last 20 | Where-Object { $_ -match $pattern } | ForEach-Object {
      if ($matches['date'] -eq $today) {
      Write-Host $matches['filename']
      }
      else {
      Write-Host "The date present in the azcopy verbose log is older"
      }
      }


      p.s. I use Get-Date -UFormat "%Y/%m/%d" because (Get-Date).ToString('yyyy/MM/dd') on my Dutch machine outputs 2018-11-10



      Regex Details



      ^                     Assert position at the beginning of the string
      [ Match the character “[” literally
      (?<date> Match the regular expression below and capture its match into backreference with name “date”
      d Match a single digit 0..9
      {4} Exactly 4 times
      / Match the character “/” literally
      d Match a single digit 0..9
      {2} Exactly 2 times
      / Match the character “/” literally
      d Match a single digit 0..9
      {2} Exactly 2 times
      )
      . Match any single character that is not a line break character
      * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      Finished transfer: Match the characters “Finished transfer:” literally
      s Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
      + Between one and unlimited times, as many times as possible, giving back as needed (greedy)
      (?<filename> Match the regular expression below and capture its match into backreference with name “filename”
      . Match any single character that is not a line break character
      * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      )
      s Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
      + Between one and unlimited times, as many times as possible, giving back as needed (greedy)
      => Match the characters “=>” literally
      . Match any single character that is not a line break character
      * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      $ Assert position at the end of the string (or before the line break at the end of the string, if any)





      share|improve this answer























      • First of all, Thanks Theo for teaching me a newer way to achieve this and i learnt a new thing today. Thanks once again. Only one thing i wanted to know, how did you created the regex pattern? can you please guide me through a link or the way you created this? It would be helpful. Thanks once again.
        – aquib.rocks
        15 hours ago








      • 2




        @aquib.rocks I have added the details for the regex. I always use RegexBuddy (not free..), but you can also experiment on regex101.com
        – Theo
        14 hours ago






      • 1




        you are more than awesome my friend, i was confused as to how the regex knew the file name, when you haven't written any code. but now i know through your explanation that it automatically know that anything before the => is the file name through regex. (?<filename>.*)s+=>.*$' Thanks brother for all the help.
        – aquib.rocks
        14 hours ago






      • 1




        @mklement0 Thanks for this. Yet again another way of getting the captured groups. As for escaping the /, I just didn't think of doing that.
        – Theo
        13 hours ago










      • Nice, but even with Select-String you don't have to match twice, because you can access the capture groups via $_.Matches[0].Groups, e.g., $_.Matches[0].Groups['filename'].Value. You don't have to resort to a Unix date format to ensure literal use of /; simply -escape it (or use embedded quoting): Get-Date -Format "yyyy/MM/dd"
        – mklement0
        13 hours ago















      up vote
      1
      down vote



      accepted







      up vote
      1
      down vote



      accepted






      To get the filenames from the log where the date is for today, you can use this:



      $logfile = 'C:CredsAzCopyVerbose.log'
      $today = Get-Date -UFormat "%Y/%m/%d"
      $pattern = '^[(?<date>d{4}/d{2}/d{2}).*Finished transfer:s+(?<filename>.*)s+=>.*$'
      Select-String -Path $logfile -Pattern $pattern | Select-Object -Last 20 | ForEach-Object {
      $null = $_.Line -match $pattern
      if ($matches['date'] -eq $today) {
      Write-Host $matches['filename']
      }
      else {
      Write-Host "The date present in the azcopy verbose log is older"
      }
      }


      Instead of using Select-String, you can also do this which requires to match the pattern only once, so a bit cleaner in my opinion:



      $logfile = 'C:CredsAzCopyVerbose.log'
      $today = Get-Date -UFormat "%Y/%m/%d"
      $pattern = '^[(?<date>d{4}/d{2}/d{2}).*Finished transfer:s+(?<filename>.*)s+=>.*$'
      Get-Content -Path $logfile | Select-Object -Last 20 | Where-Object { $_ -match $pattern } | ForEach-Object {
      if ($matches['date'] -eq $today) {
      Write-Host $matches['filename']
      }
      else {
      Write-Host "The date present in the azcopy verbose log is older"
      }
      }


      p.s. I use Get-Date -UFormat "%Y/%m/%d" because (Get-Date).ToString('yyyy/MM/dd') on my Dutch machine outputs 2018-11-10



      Regex Details



      ^                     Assert position at the beginning of the string
      [ Match the character “[” literally
      (?<date> Match the regular expression below and capture its match into backreference with name “date”
      d Match a single digit 0..9
      {4} Exactly 4 times
      / Match the character “/” literally
      d Match a single digit 0..9
      {2} Exactly 2 times
      / Match the character “/” literally
      d Match a single digit 0..9
      {2} Exactly 2 times
      )
      . Match any single character that is not a line break character
      * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      Finished transfer: Match the characters “Finished transfer:” literally
      s Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
      + Between one and unlimited times, as many times as possible, giving back as needed (greedy)
      (?<filename> Match the regular expression below and capture its match into backreference with name “filename”
      . Match any single character that is not a line break character
      * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      )
      s Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
      + Between one and unlimited times, as many times as possible, giving back as needed (greedy)
      => Match the characters “=>” literally
      . Match any single character that is not a line break character
      * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      $ Assert position at the end of the string (or before the line break at the end of the string, if any)





      share|improve this answer














      To get the filenames from the log where the date is for today, you can use this:



      $logfile = 'C:CredsAzCopyVerbose.log'
      $today = Get-Date -UFormat "%Y/%m/%d"
      $pattern = '^[(?<date>d{4}/d{2}/d{2}).*Finished transfer:s+(?<filename>.*)s+=>.*$'
      Select-String -Path $logfile -Pattern $pattern | Select-Object -Last 20 | ForEach-Object {
      $null = $_.Line -match $pattern
      if ($matches['date'] -eq $today) {
      Write-Host $matches['filename']
      }
      else {
      Write-Host "The date present in the azcopy verbose log is older"
      }
      }


      Instead of using Select-String, you can also do this which requires to match the pattern only once, so a bit cleaner in my opinion:



      $logfile = 'C:CredsAzCopyVerbose.log'
      $today = Get-Date -UFormat "%Y/%m/%d"
      $pattern = '^[(?<date>d{4}/d{2}/d{2}).*Finished transfer:s+(?<filename>.*)s+=>.*$'
      Get-Content -Path $logfile | Select-Object -Last 20 | Where-Object { $_ -match $pattern } | ForEach-Object {
      if ($matches['date'] -eq $today) {
      Write-Host $matches['filename']
      }
      else {
      Write-Host "The date present in the azcopy verbose log is older"
      }
      }


      p.s. I use Get-Date -UFormat "%Y/%m/%d" because (Get-Date).ToString('yyyy/MM/dd') on my Dutch machine outputs 2018-11-10



      Regex Details



      ^                     Assert position at the beginning of the string
      [ Match the character “[” literally
      (?<date> Match the regular expression below and capture its match into backreference with name “date”
      d Match a single digit 0..9
      {4} Exactly 4 times
      / Match the character “/” literally
      d Match a single digit 0..9
      {2} Exactly 2 times
      / Match the character “/” literally
      d Match a single digit 0..9
      {2} Exactly 2 times
      )
      . Match any single character that is not a line break character
      * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      Finished transfer: Match the characters “Finished transfer:” literally
      s Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
      + Between one and unlimited times, as many times as possible, giving back as needed (greedy)
      (?<filename> Match the regular expression below and capture its match into backreference with name “filename”
      . Match any single character that is not a line break character
      * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      )
      s Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
      + Between one and unlimited times, as many times as possible, giving back as needed (greedy)
      => Match the characters “=>” literally
      . Match any single character that is not a line break character
      * Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
      $ Assert position at the end of the string (or before the line break at the end of the string, if any)






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 14 hours ago

























      answered 15 hours ago









      Theo

      2,3661218




      2,3661218












      • First of all, Thanks Theo for teaching me a newer way to achieve this and i learnt a new thing today. Thanks once again. Only one thing i wanted to know, how did you created the regex pattern? can you please guide me through a link or the way you created this? It would be helpful. Thanks once again.
        – aquib.rocks
        15 hours ago








      • 2




        @aquib.rocks I have added the details for the regex. I always use RegexBuddy (not free..), but you can also experiment on regex101.com
        – Theo
        14 hours ago






      • 1




        you are more than awesome my friend, i was confused as to how the regex knew the file name, when you haven't written any code. but now i know through your explanation that it automatically know that anything before the => is the file name through regex. (?<filename>.*)s+=>.*$' Thanks brother for all the help.
        – aquib.rocks
        14 hours ago






      • 1




        @mklement0 Thanks for this. Yet again another way of getting the captured groups. As for escaping the /, I just didn't think of doing that.
        – Theo
        13 hours ago










      • Nice, but even with Select-String you don't have to match twice, because you can access the capture groups via $_.Matches[0].Groups, e.g., $_.Matches[0].Groups['filename'].Value. You don't have to resort to a Unix date format to ensure literal use of /; simply -escape it (or use embedded quoting): Get-Date -Format "yyyy/MM/dd"
        – mklement0
        13 hours ago




















      • First of all, Thanks Theo for teaching me a newer way to achieve this and i learnt a new thing today. Thanks once again. Only one thing i wanted to know, how did you created the regex pattern? can you please guide me through a link or the way you created this? It would be helpful. Thanks once again.
        – aquib.rocks
        15 hours ago








      • 2




        @aquib.rocks I have added the details for the regex. I always use RegexBuddy (not free..), but you can also experiment on regex101.com
        – Theo
        14 hours ago






      • 1




        you are more than awesome my friend, i was confused as to how the regex knew the file name, when you haven't written any code. but now i know through your explanation that it automatically know that anything before the => is the file name through regex. (?<filename>.*)s+=>.*$' Thanks brother for all the help.
        – aquib.rocks
        14 hours ago






      • 1




        @mklement0 Thanks for this. Yet again another way of getting the captured groups. As for escaping the /, I just didn't think of doing that.
        – Theo
        13 hours ago










      • Nice, but even with Select-String you don't have to match twice, because you can access the capture groups via $_.Matches[0].Groups, e.g., $_.Matches[0].Groups['filename'].Value. You don't have to resort to a Unix date format to ensure literal use of /; simply -escape it (or use embedded quoting): Get-Date -Format "yyyy/MM/dd"
        – mklement0
        13 hours ago


















      First of all, Thanks Theo for teaching me a newer way to achieve this and i learnt a new thing today. Thanks once again. Only one thing i wanted to know, how did you created the regex pattern? can you please guide me through a link or the way you created this? It would be helpful. Thanks once again.
      – aquib.rocks
      15 hours ago






      First of all, Thanks Theo for teaching me a newer way to achieve this and i learnt a new thing today. Thanks once again. Only one thing i wanted to know, how did you created the regex pattern? can you please guide me through a link or the way you created this? It would be helpful. Thanks once again.
      – aquib.rocks
      15 hours ago






      2




      2




      @aquib.rocks I have added the details for the regex. I always use RegexBuddy (not free..), but you can also experiment on regex101.com
      – Theo
      14 hours ago




      @aquib.rocks I have added the details for the regex. I always use RegexBuddy (not free..), but you can also experiment on regex101.com
      – Theo
      14 hours ago




      1




      1




      you are more than awesome my friend, i was confused as to how the regex knew the file name, when you haven't written any code. but now i know through your explanation that it automatically know that anything before the => is the file name through regex. (?<filename>.*)s+=>.*$' Thanks brother for all the help.
      – aquib.rocks
      14 hours ago




      you are more than awesome my friend, i was confused as to how the regex knew the file name, when you haven't written any code. but now i know through your explanation that it automatically know that anything before the => is the file name through regex. (?<filename>.*)s+=>.*$' Thanks brother for all the help.
      – aquib.rocks
      14 hours ago




      1




      1




      @mklement0 Thanks for this. Yet again another way of getting the captured groups. As for escaping the /, I just didn't think of doing that.
      – Theo
      13 hours ago




      @mklement0 Thanks for this. Yet again another way of getting the captured groups. As for escaping the /, I just didn't think of doing that.
      – Theo
      13 hours ago












      Nice, but even with Select-String you don't have to match twice, because you can access the capture groups via $_.Matches[0].Groups, e.g., $_.Matches[0].Groups['filename'].Value. You don't have to resort to a Unix date format to ensure literal use of /; simply -escape it (or use embedded quoting): Get-Date -Format "yyyy/MM/dd"
      – mklement0
      13 hours ago






      Nice, but even with Select-String you don't have to match twice, because you can access the capture groups via $_.Matches[0].Groups, e.g., $_.Matches[0].Groups['filename'].Value. You don't have to resort to a Unix date format to ensure literal use of /; simply -escape it (or use embedded quoting): Get-Date -Format "yyyy/MM/dd"
      – mklement0
      13 hours ago














      up vote
      0
      down vote













      Below is an approach using regex for date.



      $var = Select-String -Path "C:CredsAzCopyVerbose.log" -Pattern 'Finished Transfer' | 
      Select-Object -Last 20 | ForEach-Object -Process {
      $_.Line -match 'd{4}/d{2}/d{2}' | Out-Null
      [string]$Match = $Matches.Values
      if ([Datetime]$Match -eq (Get-Date).ToString('yyyy/MM/dd'))
      {
      $_.Line. // There is no method which I'm aware of need help in this if statement
      }
      Else {Write-Host "The date present in the azcopy verbose log is older"}
      }





      share|improve this answer

























        up vote
        0
        down vote













        Below is an approach using regex for date.



        $var = Select-String -Path "C:CredsAzCopyVerbose.log" -Pattern 'Finished Transfer' | 
        Select-Object -Last 20 | ForEach-Object -Process {
        $_.Line -match 'd{4}/d{2}/d{2}' | Out-Null
        [string]$Match = $Matches.Values
        if ([Datetime]$Match -eq (Get-Date).ToString('yyyy/MM/dd'))
        {
        $_.Line. // There is no method which I'm aware of need help in this if statement
        }
        Else {Write-Host "The date present in the azcopy verbose log is older"}
        }





        share|improve this answer























          up vote
          0
          down vote










          up vote
          0
          down vote









          Below is an approach using regex for date.



          $var = Select-String -Path "C:CredsAzCopyVerbose.log" -Pattern 'Finished Transfer' | 
          Select-Object -Last 20 | ForEach-Object -Process {
          $_.Line -match 'd{4}/d{2}/d{2}' | Out-Null
          [string]$Match = $Matches.Values
          if ([Datetime]$Match -eq (Get-Date).ToString('yyyy/MM/dd'))
          {
          $_.Line. // There is no method which I'm aware of need help in this if statement
          }
          Else {Write-Host "The date present in the azcopy verbose log is older"}
          }





          share|improve this answer












          Below is an approach using regex for date.



          $var = Select-String -Path "C:CredsAzCopyVerbose.log" -Pattern 'Finished Transfer' | 
          Select-Object -Last 20 | ForEach-Object -Process {
          $_.Line -match 'd{4}/d{2}/d{2}' | Out-Null
          [string]$Match = $Matches.Values
          if ([Datetime]$Match -eq (Get-Date).ToString('yyyy/MM/dd'))
          {
          $_.Line. // There is no method which I'm aware of need help in this if statement
          }
          Else {Write-Host "The date present in the azcopy verbose log is older"}
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 16 hours ago









          PRASOON KARUNAN V

          1,2981621




          1,2981621






















              up vote
              0
              down vote













              To complement Theo's helpful answer:



              It is not obvious, but it is possible to access a Select-String command's [named] capture-group matches in a ForEach-Object script block (no need to repeat matching with -match):



              PS> '... File transfer: C:pathtofile => ...' |
              Select-String 'bFile transfer: (?<file>.+?) =>' |
              ForEach-Object { $_.Matches[0].Groups['file'].Value }
              C:pathtofile # Value of named capture group 'file'



              • $_.Matches is the collection of matches for the current input line; unless -AllMatches was specified, there's only one entry, with index 0.


              • .Groups accesses the collection of capture-group matches (with the entry at index 0 containing the overall match).


              • ['file'] accesses the match for named capture group file, but note that at index-based access works equally (for unnamed capture groups), starting with index 1; that is, $_.Matches[0].Groups[1].Value in the command above would have yielded the same result.







              share|improve this answer

























                up vote
                0
                down vote













                To complement Theo's helpful answer:



                It is not obvious, but it is possible to access a Select-String command's [named] capture-group matches in a ForEach-Object script block (no need to repeat matching with -match):



                PS> '... File transfer: C:pathtofile => ...' |
                Select-String 'bFile transfer: (?<file>.+?) =>' |
                ForEach-Object { $_.Matches[0].Groups['file'].Value }
                C:pathtofile # Value of named capture group 'file'



                • $_.Matches is the collection of matches for the current input line; unless -AllMatches was specified, there's only one entry, with index 0.


                • .Groups accesses the collection of capture-group matches (with the entry at index 0 containing the overall match).


                • ['file'] accesses the match for named capture group file, but note that at index-based access works equally (for unnamed capture groups), starting with index 1; that is, $_.Matches[0].Groups[1].Value in the command above would have yielded the same result.







                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  To complement Theo's helpful answer:



                  It is not obvious, but it is possible to access a Select-String command's [named] capture-group matches in a ForEach-Object script block (no need to repeat matching with -match):



                  PS> '... File transfer: C:pathtofile => ...' |
                  Select-String 'bFile transfer: (?<file>.+?) =>' |
                  ForEach-Object { $_.Matches[0].Groups['file'].Value }
                  C:pathtofile # Value of named capture group 'file'



                  • $_.Matches is the collection of matches for the current input line; unless -AllMatches was specified, there's only one entry, with index 0.


                  • .Groups accesses the collection of capture-group matches (with the entry at index 0 containing the overall match).


                  • ['file'] accesses the match for named capture group file, but note that at index-based access works equally (for unnamed capture groups), starting with index 1; that is, $_.Matches[0].Groups[1].Value in the command above would have yielded the same result.







                  share|improve this answer












                  To complement Theo's helpful answer:



                  It is not obvious, but it is possible to access a Select-String command's [named] capture-group matches in a ForEach-Object script block (no need to repeat matching with -match):



                  PS> '... File transfer: C:pathtofile => ...' |
                  Select-String 'bFile transfer: (?<file>.+?) =>' |
                  ForEach-Object { $_.Matches[0].Groups['file'].Value }
                  C:pathtofile # Value of named capture group 'file'



                  • $_.Matches is the collection of matches for the current input line; unless -AllMatches was specified, there's only one entry, with index 0.


                  • .Groups accesses the collection of capture-group matches (with the entry at index 0 containing the overall match).


                  • ['file'] accesses the match for named capture group file, but note that at index-based access works equally (for unnamed capture groups), starting with index 1; that is, $_.Matches[0].Groups[1].Value in the command above would have yielded the same result.








                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 10 hours ago









                  mklement0

                  120k19231259




                  120k19231259






























                       

                      draft saved


                      draft discarded



















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237758%2fparsing-the-log-file-using-select-string%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest




















































































                      Popular posts from this blog

                      Xamarin.iOS Cant Deploy on Iphone

                      Glorious Revolution

                      Dulmage-Mendelsohn matrix decomposition in Python