0

There are about ten lines of data. For each line of data I want to indicate whether that line contains numerals.

How can I print out "yes, this line has numerals" or "no, this line has no numerals" for each and every line, exactly once?

output:

thufir@dur:~/flwor/csv$ 
thufir@dur:~/flwor/csv$ pwsh import.ps1 
no digits

Name
----                                                                           
people…                                                                        

thufir@dur:~/flwor/csv$ 

code:

$text = Get-Content -Raw ./people.csv
[array]::Reverse($text)

$tempAttributes = @()
$collectionOfPeople = @()

ForEach ($line in $text) { 
  if($line -notmatch '.*?[0-9].*?') {
    $tempAttributes += $line 
    Write-Host "matches digits"   
  }
  else {
    Write-Host "no digits"   
    $newPerson = [PSCustomObject]@{
      Name       = $line
      Attributes = $tempAttributes
    }
    $tempAttributes = @()
    $collectionOfPeople += $newPerson
  }
}

$collectionOfPeople

data:

people
joe
phone1
phone2
phone3
sue
cell4
home5
alice
atrib6
x7
y9
z10

The only reason I'm printing "digits" or "no digits" is as a marker to aid in building the object.

Thufir
  • 8,216
  • 28
  • 125
  • 273
  • 1
    How about every time the text matches `^[^0-9]+$`, you print No Digits – Robo Mop Feb 16 '20 at 10:39
  • 1
    Currently, your code will print No Digits every time there's something that does not match `[0-9]`. Do you see the problem? Every time it encounters a letter, it will print No Digits. – Robo Mop Feb 16 '20 at 10:40
  • I want it to print "no digits" every time it encounters a string lacking digits...so at least three times (joe, sue, alice). I'll update the question to try and clarify. Not sure that I follow your thinking. I don't want it to print "no digits" more than four times...certainly not for every character in a String of data... **the print is just a marker to ensure the logic is working** – Thufir Feb 16 '20 at 10:44
  • 1
    Currently, your code tells the regex to match ANYTHING that is not `[0-9]`, given by your code `$line -notmatch '[0-9]'`. Try to think about it from the computer's perspective, without common sense. 'J' is not a digit. 'o' is not a digit. 'e' is not a digit. So when it encounters 'Joe', it will print "No digits" **3** times. – Robo Mop Feb 16 '20 at 10:48
  • 1
    Please try this code instead, `if($line -notmatch '.*?[0-9].*?')` – Robo Mop Feb 16 '20 at 10:49
  • @RoboMop Thanks, I added that `regex`, I see what you mean. I updated the question to try and clarify what output I'm looking for. – Thufir Feb 16 '20 at 10:57
  • The output you've edited in the question - is that the output you're getting, or the one that you desire? – Robo Mop Feb 16 '20 at 10:57
  • that's the output I'm getting. I'd like to see output for each line: yes / no. does this line have numerals? Perhaps the `if` statement is running on the whole file itself?? – Thufir Feb 16 '20 at 10:59
  • 1
    I have zero knowledge about powershell, and I was trying to answer this with my experience with regex. It may very well be that - $line in $text may be giving you the entire file instead of one line – Robo Mop Feb 16 '20 at 11:09
  • @RoboMop it was quite helpful! No worries. Thanks :) – Thufir Feb 16 '20 at 11:30

1 Answers1

1

You can use the following:

switch -regex -file people.csv {
    '\d' { "yes" ; $_ }
    default { "no"; $_ }
}

\d is a regex character matching a digit. A switch statement with -regex allows for regex expressions to be used for matching text. The default condition is picked when no other condition is met. $_ is the current line being processed.

switch is generally faster than Get-Content for line by line processing. Since you do want to perform certain actions per line, you likely don’t want to use the -Raw parameter because that will read in all file contents as one single string.


# For Reverse Output
$output = switch -regex -file people.csv {
    '\d' { "yes" ; $_ }
    default { "no"; $_ }
}
$output[($output.GetUpperBound(0))..0)]
AdminOfThings
  • 23,946
  • 4
  • 17
  • 27
  • Thanks, that works. Perhaps a seperate question, but how could I reverse the input (read from bottom to top)? I want to add each line to a custom object depending on the yes/no result. – Thufir Feb 16 '20 at 11:29
  • 1
    You can just store the output in a variable and print it in reverse. See the edited code – AdminOfThings Feb 16 '20 at 11:39