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}}
4
  • 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. Commented Aug 16, 2021 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]. Commented Aug 16, 2021 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. Commented Aug 16, 2021 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 Commented Aug 17, 2021 at 18:09

1 Answer 1

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++
    }
Sign up to request clarification or add additional context in comments.

3 Comments

I think OP is checking if his Csv (pipeline delimited) has 210 columns exactly which would explain his usage of Get-Content.
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.
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!

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.