2

Good evening. Stack Overflow and Powershell novice here.

The below piece of code in Powershell is returning more values than I wanted. For example, it is capturing variables in a JSON file that match PPVCOUNT but also variables named with characters before and after the PPVCount string. Example:

PPVCountAtInception

OperatorCountGreaterThanPPVCountIndicator

GOAL: My goal is to have the code only return the variable PPVCount. I also want to keep the columns: Pattern, LineNumber, Line. Forgive me for my lack of knowledge and thank you in advance

$file = 'C:\\Users\\B187515\\Downloads\\j.json'
$PPVCount="PPVCount"

Get-Content $file | Select-String -Pattern $PPVCount -Context 1| Select-Object Pattern,LineNumber, Line -ExpandProperty Context -First 18 | Format-Table | Out-file -FilePath 'C:\\Users\\B187515\\Downloads\\test.csv' -Append

Expected results:

My goal is to have the code only return the variable "PPVCount" in the CSV file. I also want to keep the columns: Pattern, LineNumber, Line

Actual results There are multiple variables returning contain "PPVCount" somewhere in the variable name. See screenshot of CSV enter image description here

4
  • 1
    remove Format-Table and change Out-File to Export-Csv Commented Aug 1, 2024 at 2:22
  • So the pattern you're looking for is "PPVCount": Commented Aug 1, 2024 at 8:55
  • 1
    -Pattern uses regex. To get only line that start with PPVCount use "^PPVCount" or only contain use "^PPVCount$" Commented Aug 1, 2024 at 9:35
  • 1
    As an aside: while benign in file paths, there's no reason to use \\ instead of \ in PowerShell. \ is not the escape char. in PowerShell, ` is. Commented Aug 1, 2024 at 10:42

1 Answer 1

1

Building on the helpful comments:

# Note: Just use '\' - no need for '\\'
$file = 'C:\Users\B187515\\Downloads\j.json'

# Enclose the property name to search for in embedded "..."
$searchRegex ='"PPVCount"'

# Pass $file (the file to search through) directly to Select-String, 
# and use Export-Csv to export the results to a CSV file.
Select-String -LiteralPath $file -Pattern $searchRegex -Context 1 | 
  Select-Object Pattern, LineNumber, Line -ExpandProperty Context -First 18 | 
  Export-Csv -LiteralPath 'C:\Users\B187515\Downloads\test.csv'
  • Your intent is to look for string PPVCount as a separate word; since you seem to be looking for this string as a JSON property name, you can assume that it is enclosed in embedded "..." and can therefore make it part of the search string.

    • Since this amounts to a literal search, you can add the -SimpleMatch switch, which likely improves performance.

    • Generally, to look for a token consisting only of letters, numbers, or _ as a separate word, you can use word-boundary assertions aka anchor (which is a regex feature and therefore requires you not to use -SimpleMatch), so the alternative in your case would be to use $searchRegex ='\bPPVCount\b'

  • Since your intent is to create a CSV file, use Export-Csv to create it.

    • As for what you used: Both Format-Table and Out-File create representations of data for the human observer, which is why you should never use them to print data for programmatic processing - see this answer for more information.

    • Character-encoding caveat: In Windows PowerShell (versions up to v5.1), Export-Csv inexplicably defaults to ASCII(!) encoding; whereas in PowerShell (Core) 7 it is commendably BOM-less UTF-8. Use an -Encoding argument as needed, but note that -Encoding utf8 invariably creates a UTF-8 file with a BOM in Windows PowerShell.

  • A couple of asides:

    • While benign in file paths, there's no reason to use \\ instead of \ in PowerShell. \ is not the escape char. in PowerShell, ` is - see the about_Special_Characters help topic.

    • The above passes the path of the file to search through directly to Select-String, via its -LiteralPath parameter. This is much more efficient than piping the lines of the file one by one to it via Get-Content, and is required if you want to see line numbers alongside the matching lines in the default display output.

Sign up to request clarification or add additional context in comments.

4 Comments

thank you all for your responses. I used $searchRegex ='"PPVCount"' , removed the \\, but I kept the Format-Table and Out-File because I am visually verifying the results.
Hi @mklement0 Sometimes the output in the csv file isn't showing enough characters in that string. Is there a way to make the string longer? For example, if you look at the image I posted in the original post, I have a PostContext value like "Boolvalue":true. But sometimes my output in the CSV gets cut short and reads "boolVal" and I can't tell if the value it true of false. I only want to modify the existing code and not re-do everything I coded. Does that make sense? Thank you in advance
@BigSmooth, Format-Table can result in truncation of values, which is one of the reasons combining Select-Object and Export-Csv is preferable. If you want Format-Table to assume a certain line width that is big enough to show all values without truncation, you can pass a -Width argument to Out-File.
Thank you @mklement0 stackoverflow.com/users/45375/mklement0 I also posted a new issue in a separate through. This is helpful. Can you please assist there as well? stackoverflow.com/questions/78836394/…

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.