SkullNerd
SkullNerd

Reputation: 57

Powershell - how can I make

Trying to find the numbers in my file divisible by 3. How can I make my for each loop read each number individually?

this is my file:
    6 9 7   
    -----   
    5 2 9   
    3 4 4   
    1 6 9 

This is my code so far:

function number{
    param($b)

    # Loop through all lines of input
    foreach($a in $b){

        if ($line = % 3)
            {
            Write-Output "divisible by 3"
         }
         else {
            Write-Output "number not divisible by 3"
         }   
        }
       } 


#Variables

#Get input from csv file
$a = Import-Csv "document 2.Dat"

Upvotes: 0

Views: 124

Answers (1)

TessellatingHeckler
TessellatingHeckler

Reputation: 28963

How have you got this far in, without realising that none of that even does anything at all? Whatever development approach you're using, you need to rethink it.

Hints that something is wrong:

`import-csv "document 2.Dat"

How is it printing more dashes than there even are in the file? What is it actually printing? Use useful debugging/testing tool, wrap each thing in dashes so you can see where they start and end:

<code>Import-Csv 'D:\document 2.dat' | foreach { "-$_-" }</code>

Oh that's broken.

Inside function number { put write-host 'hello?' and see that it's never printing anything.

Try calling the function by hand to see what it does:

<code>number '5 6 7'</code>

Oh I have no idea what number is not divisible by 3, I'd better fix that so I can see what's going on.

And if you have an eye looking for details

<code>screenshot of function code</code>

where does $line get assigned? What is = doing in an if test? What is % 3 doing with nothing to the left of the %? Why am I using variable names like $a and $b which don't help me follow what's happening at all?

and, of course, "*why am I not write-host "..." all the way through, and/or stepping through this code in the debugger to see what's happening?


  1. Google(*) "read file powershell"

google for "read file powershell"

  1. Try it

get-content 'd:\document 2.dat'

That's my file alright. And the limits of the output are ... lines. Cool.

  1. function number I should give it a better name but.

Sigh. alright, alright.

function Get-NumbersWhichDivideEvenlyByThree

No output, even from a simple 'hi'? Ah, call the function.

Call function, see output

Great.

Pass a parameter to it and print it...

change function to accept a param and print it

No output.

Enough screenshots.

  1. Pass a parameter when calling the function. Get-NumbersWhichDivideEvenlyByThree $FileContent

  2. Iterate over the lines and print them inside the function.

  3. Google "powershell get numbers from string" and stuff

  4. Iteratively develop your code, going from working block to working block. Never end up in a position where you have a dozen lines that all don't work in half a dozen different ways all at once, and nowhere to go from there.

Bit you actually asked

Get numbers out of a string.

Use regex. This is exactly why they exist. But to try and keep it simple - in a way that's actually more complicated but tough - break the lines apart on spaces, and pick out the pieces which are numbers and throw the rest away.

To get this with a reasonably nice answer, you almost need to just magically know about -split, perhaps by stumbling on one of @mklement0's answers here about unary split or split has an unary form or the unary form of the -split operator is key here , or, I guess, have read help about_Split in careful detail.

-split '6 9 7'   # this splits the line into parts on *runs* of whitespace

6
9
7   # look like numbers, but are strings really

So you get some text pieces, including the line of ----- in the file, that will be among them. And you need to test which are numbers and keep them, and which are dashes (letters, punctuation, etc) and throw those away.

$thing -as [int]    # will try to cast $thing as a (whole) number, and silently fail (no exception) if it cannot.

# Split the line into pieces. Try to convert each piece to a number.
# Filter out the ones which weren't numbers and failed to convert.
$pieces  = -split $line
$pieces  = $pieces | ForEach-Object { $_ -as [int] }
$numbers = $pieces | Where-Object   { $_ -ne $null }

Then you can do the % 3 test. And have code like:

function Get-NumbersWhichDivideEvenlyByThree {
    param($lines)

    foreach ($line in $lines)
    {

        $pieces  = -split $line
        $pieces  = $pieces | ForEach-Object { $_ -as [int] }
        $numbers = $pieces | Where-Object { $_ -ne $null }

        foreach ($number in $numbers)
        {
            if (0 -eq $number % 3)
            {
                Write-Output "$number divisible by 3"
            }
            else
            {
                Write-Output "$number not divisible by 3"
            }
        }

    }
}

$FileContent = Get-Content 'D:\document 2.dat'
Get-NumbersWhichDivideEvenlyByThree $FileContent

and output like:

Example output of working program


  1. (-split(gc D:\test.txt -Raw)-match'\d+')|%{"$_$(('',' not')[$_%3]) divisible by 3"}

Upvotes: 4

Related Questions