2

The text file is numbers.txt:

1;2;5;6;1;3
9;6;16;9;2
6;23;3
3;8;9

My code is:

$a = Get-Content .\numbers.txt
$maximum = 0
foreach ($i in $a) {
    if ([int]$i.Split(";") -gt $maximum) {
        $maximum = $i.Split(";")
    }
}
$maximum

I know, there is something wrong with the types (string-integer), but I don't know how to fix it.

PS: If I do it this way, it works, but it's a time-consuming solution to find the max value for every column separately:

$a = Get-Content .\numbers.txt
$maximum = 0
foreach ($i in $a) {
    if ([int]$i.Split(";")[0] -gt $maximum) {
        $maximum = $i.Split(";")[0]
    }
}
$maximum
1
  • Maximum value for each row or for the whole content? Commented Dec 13, 2017 at 6:20

4 Answers 4

3

I know, there is something wrong with the types (string-integer), but I don't know how to fix it

What's wrong is that $a is the lines in the file and $i is a line and you need to split that separately into numbers:

$a = get-content .\numbers.txt
$maximum = 0
foreach ( $line in $a )
{
    foreach ( $i in $line.Split(';') )
    {
        if ( [int]$i -gt $maximum )
        {
            $maximum = [int]$i
        }
    }
}
$maximum

But also what's wrong is that you're writing (Java/C#/Python/C/otherlang) in PowerShell, this is not good PowerShell habits.

Get-Content .\numbers.txt | 
    ForEach-Object { $_.Split(';') } | 
    Measure-Object -Maximum |
    Select-Object -ExpandProperty Maximum

Or if you want it short and type-able:

gc .\numbers.txt | foreach split ';' | measure -max
Sign up to request clarification or add additional context in comments.

Comments

1

For the whole file:

Get-Content -Path .\Numbers.txt | 
    ForEach-Object {
        $_.Split(';')
    } | ForEach-Object {
        [int]$_
    } | Measure-Object -Maximum |
    Select-Object -ExpandProperty Maximum 

9 Comments

You probably don't need the cast here and can omit | ForEach-Object { [int]$_ }
Maybe, but I'm on mobile and can't test. Either way, I'd rather not assume that Measure-Object is smart enough to convert strings to ints, or smart enough to evaluate things automagically. "Maximum" and "Minimum" have conventional definitions for strings, after all.
@("1","2", "4", "3") | Measure-Object -Maximum | Select Maximum outputs 4. So yes, the 2nd cast can be omitted.
@Clijsters No, that doesn't prove it's not sorting strings. It's definitely doing some form of automagic typing, however, since '1','23','3' returns 23, but '1','23','3','Test' returns Test.
How does your observation conflict with mine? If you put a char to a function for measuring numbers, you will either get an exception (your [int] cast) or it will just calculate the maximum for that String. (One calls it unexpected behavior, I think it's totally ok to do so)
|
0

You could use the Measure-Object cmdlet with the -Maximum switch do determine the maximum value after you have removed every new line character from the text file and splitting the values:

(Get-Content numbers.txt -raw) -replace [system.environment]::NewLine, ';' -split ';' |
     Measure-Object -Maximum |
     Select -ExpandProperty Maximum

If your files containing any whitespace character you have to remove them first by adding -replace '\s+' before the first -replace

1 Comment

Instead of converting the NewLines to semi-colons how about just expanding your split regex to include them?
0

I would use the -raw option of the Get-Content which means the whole thing can be done with a simple regex split. Something like this:

((Get-Content numbers.txt -raw) -split '[\r\n;]+' | Measure-Object -Maximum).Maximum

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.