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
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.