1

I found an answer to a previous question incredibly helpful, but I can't quite figure out how Get-Content is able able to store the 'line number' from the input.

Basically I'm wondering if PSObjects store information such as line number or row number. In the example below, it is basically like using Get-Content is able to store the line number as a variable you can use later. In the pipeline, the variable would be $_.psobject.Properties.value[5]

A bit of that seems redundant to me since $_ is an object (I think), but still it is very cool that .value[5] seems to be the line number or row number. The same is not true of Import-CSV and while I'm looking for a similar option with Import-CSV; I'd like to better understand why this works the way it does.

https://stackoverflow.com/a/23119235/15243610

Get-Content $colCnt | ?{$_} | Select -Skip 1 | %{if(!($_.split("|").Count -eq 210)){"Process stopped at line number $($_.psobject.Properties.value[5]), incorrect column count of: $($_.split("|").Count).";break}}
immobile2
  • 489
  • 2
  • 15
  • 1
    If you want to have an index you could save the imported CSV file to a variable - lets name it `$CSV` - and use a `for` loop to iterate over it from `1` to `$CSV.Count`. Now you can use the loop variable as an index. – Olaf Aug 16 '21 at 22:03
  • 2
    Man, sometimes even I am left wondering how I came up with some of my old answers. @SantiagoSquarzon is completely right, the 6th property is `ReadCount`. I have no idea why I wrote that the way I did, just doing `$_.ReadCount` would be much simpler than `$_.psobject.Properties.Value[5]`. – TheMadTechnician Aug 16 '21 at 22:19
  • 1
    @TheMadTechnician lol I deleted my comment because the question was related to `Import-Csv` but yeah, each element outputted by `Get-Content` has the `ReadCount` property assuming the `-Raw` switch is not in place. – Santiago Squarzon Aug 16 '21 at 22:42
  • Awesome - thanks for the input, makes a lot of sense. Two final questions: 1) How do I get my code block to scroll left/right instead of looking weird like it does? 2) I figured out how to mark the answer – immobile2 Aug 17 '21 at 18:09

1 Answers1

4

The answer in the other question works because Get-Content does indeed include the line number when it reads in the strings. When you run Get-Content each line will have a $_.ReadCount property as the 6th property on the object, which in my old answer I referenced in the PSObject for it as $_.psobject.Properties.value[5] (it was 7 years ago and I didn't know better yet, sorry). Mind you, if you use the -ReadCount parameter it will send that many lines through at a time, so Get-Content $file -readcount 5 | Select -first 1 | ForEach-Object{ $_.ReadCount } will come out as 5. Also -Raw sends everything through at once so it won't work with that.

Honestly, this isn't that hard to adapt to Import-Csv, we just increment a variable defined in the ForEach-Object loop.

Import-Csv C:\Path\To\SomeFile.csv | ForEach-Object -Begin {$x=1} -Process {
        If($_.Something -eq $SomethingElse){
            Write-Warning "Somethin' bad happened on line $x!"
            break
        }else{$_}
        $x++
    }
mklement0
  • 382,024
  • 64
  • 607
  • 775
TheMadTechnician
  • 34,906
  • 3
  • 42
  • 56
  • I think OP is checking if his Csv (pipeline delimited) has 210 columns exactly which would explain his usage of `Get-Content`. – Santiago Squarzon Aug 16 '21 at 23:22
  • That line is copied/pasted directly from my answer in the question he linked. Unless he coincidentally is looking for the exact same amount of pipe delimiters as the other user, which seems really unlikely. – TheMadTechnician Aug 16 '21 at 23:38
  • 1
    Well actually I was using it to check the number of columns, however I was checking for -eq 11 instead of 210; super helpful pipeline that you came up with @TheMadTechnician - I just couldn't figure out why ...value[5] was useful. $_.ReadCount makes sense! – immobile2 Aug 17 '21 at 18:08