powershellselect-string

How to Handle Select-String returning System.Object[]


I am aware of this question. It doesn't quite answer my question (or I'm failing to understand how to apply it).

I am attempting to search a selection of files in a directory for strings that may be ipv4 addresses. I am using the below code. I am fine with it over-matching things like version strings, and am prepared to manually ignore them.

gci -include *.vb,*.config, *.frm, *.dsr, *.cls, *.bas, *.iss, *.h, *.cs, *.resx, *.json, *.yml, *.xaml, *.wxs, *.wxi, *.wxl, *.cpp -recurse | % {
@'
File name - {0}
{1}
.....................
'@ -f $_.FullName, (get-content $_.FullName | select-string -pattern '^.*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}.*$' )
} | out-file -filepath .\ips.txt

More often than not, the results are a System.Object[], rather than a string. I understand that this means multiple matches out of the Select-String.

How do I unfold these items while still working correctly with the single result lines?


Solution

  • Your task might be as easy as piping the output from Get-ChildItem to Select-String directly then selecting the .Path (source) and .Line properties and lastly exporting to a Csv file:

    Get-ChildItem -Include *.vb, *.config, *.... -Recurse |
        Select-String '^.*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}.*$' |
        Select-Object Path, Line |
        Export-Csv path\to\csv.csv -NoTypeInformation
    

    If you wanted to export to a plain text file you would first need to join all matched lines (the array of .Line outputted by Select-String) with a new line character to construct a single string, then you can interpolate that string:

    Get-ChildItem -Include *.vb, *.config, *.... -Recurse | ForEach-Object {
        $lines = ($_ | Select-String '^.*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}.*$').Line -join [Environment]::NewLine
        'File name - {0}{1}{2}{1}.....................' -f $_.FullName, [Environment]::NewLine, $lines
    } | Out-File -FilePath .\ips.txt