Home > Blockchain >  How do I use Get-Content to retrieve specific line and column from text file
How do I use Get-Content to retrieve specific line and column from text file

Time:03-16

Example from the iperf3.txt file created.

[SUM] 0.00-30.00 sec 1.09 GBytes 312 Mbits/sec sender
[SUM] 0.00-30.00 sec 1.09 GBytes 312 Mbits/sec receiver

I would like to be able to "extract" the 312 Mbits/sec-text and leave the rest alone. Previous I've used this line of code to "present" the numbers from the iPerf-speedtest after the PS-script was completed, but the entire line is displayed like the example, I put in above.

Get-Content -Path $iperf3.txt | Where-Object {$_ -like'*[SUM]*0.00-15.00*'}

I've been looking at this post Get filtered content from text file with Get-Content and wondered if that is what is needed to do what I want.

I would like to end result to be something like this:

Your speedtest result is 123 Mbits/sec for download.
Your speedtest result is 321 Mbits/sec for upload.

Any input or feedback would be appreciated. Thanks!

EDITED/UPDATED
More text from the text-file.

[ ID] Interval Transfer Bandwidth Retr
[ 5] 0.00-30.00 sec 116 MBytes 32.5 Mbits/sec 91 sender
[ 5] 0.00-30.00 sec 116 MBytes 32.3 Mbits/sec receiver
[ 7] 0.00-30.00 sec 116 MBytes 32.6 Mbits/sec 94 sender
[ 7] 0.00-30.00 sec 116 MBytes 32.4 Mbits/sec receiver
[ 9] 0.00-30.00 sec 109 MBytes 30.5 Mbits/sec 107 sender
[ 9] 0.00-30.00 sec 108 MBytes 30.2 Mbits/sec receiver
[ 11] 0.00-30.00 sec 120 MBytes 33.5 Mbits/sec 98 sender
[ 11] 0.00-30.00 sec 119 MBytes 33.3 Mbits/sec receiver
[ 13] 0.00-30.00 sec 108 MBytes 30.2 Mbits/sec 101 sender
[ 13] 0.00-30.00 sec 107 MBytes 29.9 Mbits/sec receiver
[ 15] 0.00-30.00 sec 123 MBytes 34.3 Mbits/sec 104 sender
[ 15] 0.00-30.00 sec 122 MBytes 34.0 Mbits/sec receiver
[ 17] 0.00-30.00 sec 102 MBytes 28.5 Mbits/sec 104 sender
[ 17] 0.00-30.00 sec 101 MBytes 28.3 Mbits/sec receiver
[ 19] 0.00-30.00 sec 108 MBytes 30.2 Mbits/sec 108 sender
[ 19] 0.00-30.00 sec 107 MBytes 30.0 Mbits/sec receiver
[ 21] 0.00-30.00 sec 103 MBytes 28.8 Mbits/sec 105 sender
[ 21] 0.00-30.00 sec 102 MBytes 28.6 Mbits/sec receiver
[ 23] 0.00-30.00 sec 125 MBytes 34.9 Mbits/sec 96 sender
[ 23] 0.00-30.00 sec 124 MBytes 34.6 Mbits/sec receiver
[SUM] 0.00-30.00 sec 1.10 GBytes 316 Mbits/sec 1008 sender
[SUM] 0.00-30.00 sec 1.10 GBytes 314 Mbits/sec receiver

For each speedtest iPerf will add the above content to the text-file, so in theory it will could be added two-three times. Hope this helps.

CodePudding user response:

Not knowing if there is more text in that file and how large it may be, here's two options for you:

Get-Content -Path 'D:\Test\iperf3.txt'| 
Where-Object { $_ -match '\[SUM].*\s(\d  Mbits/sec) (\w )$'} | 
ForEach-Object {
    # define the text. if 'sender' then 'upload', otherwise 'download'
    $updown = if ($matches[2] -eq 'sender') { 'upload' } else { 'download' }
    'Your speedtest result is {0} for {1}' -f $matches[1], $updown
}

If the file is huge, this would work faster and consumes less memory:

switch -Regex -File 'D:\Test\iperf3.txt' {
    '\[SUM].*\s(\d  Mbits/sec) (\w )$' {
        # define the text. if 'sender' then 'upload', otherwise 'download'
        $updown = if ($matches[2] -eq 'sender') { 'upload' } else { 'download' }
        'Your speedtest result is {0} for {1}' -f $matches[1], $updown
    }
}

Regex details:

\[                  Match the character “[” literally
SUM]                Match the characters “SUM]” 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)
\s                  Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
(                   Match the regular expression below and capture its match into backreference number 1
   \d               Match a single digit 0..9
                    Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   \ Mbits/sec      Match the characters “ Mbits/sec” literally
)                  
\                   Match the character “ ” literally
(                   Match the regular expression below and capture its match into backreference number 2
   \w               Match a single character that is a “word character” (letters, digits, etc.)
                    Between one 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)

Now that you have shown more of the file, I noticed that the lines sender all have an extra numeric value in front of the word sender, which wasn't there in your earlier example.

Because of that, we need to adjust the regex.

This new code should ten work:

switch -Regex -File 'D:\Test\iperf3.txt' {
    '\[SUM].*\s(\d  Mbits/sec)\s(?:[^\s] \s)?(\w )$' {
        # define the text. if 'sender' then 'upload', otherwise 'download'
        $updown = if ($matches[2] -eq 'sender') { 'upload' } else { 'download' }
        'Your speedtest result is {0} for {1}' -f $matches[1], $updown
    }
}

Regex details:

\[                      Match the character “[” literally
SUM]                    Match the characters “SUM]” 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)
\s                      Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
(                       Match the regular expression below and capture its match into backreference number 1
   \d                   Match a single digit 0..9
                        Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   \ Mbits/sec          Match the characters “ Mbits/sec” literally
)
\s                      Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
(?:                     Match the regular expression below
   [^\s]                Match any character that is NOT a “A whitespace character (spaces, tabs, line breaks, etc.)”
                        Between one 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 zero and one times, as many times as possible, giving back as needed (greedy)
(                       Match the regular expression below and capture its match into backreference number 2
   \w                   Match a single character that is a “word character” (letters, digits, etc.)
                        Between one 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)

CodePudding user response:

Thanks to Theo for the feedback. I believe that I need to spent some time reading up upon RegEx and perhaps post another question in the future about RegEx and the use of it.

  • Related