I have the following script to find files containing a certain string and then report on the location of the file along with the size in bytes.
It works, but I seem to have made heavy weather of finding the string which involves a fair bit of tidying up afterwards to produce some clean output.
Any idea how I could make this more concise?
# Ignore errors
$ErrorActionPreference= 'silentlycontinue'
# Grab user options
$ext = Read-Host -Prompt "Enter extension "
$huntString = Read-Host -Prompt "Enter hunt string "
# Find text files (.log, .txt etc) containing the hunt string
$entries = gci -recurse -include *.$ext -ErrorAction SilentlyContinue | select fullname, length | sort -property length
echo ''
foreach ($e in $entries)
{
# Find files containing the hunt string
$foundFile = (gci $e.fullname | select-string $huntString | measure-object | findstr Count)
# Output hit count along with size and name
$rawOutput = $foundFile.ToString() + $e.Length.ToString().PadRight(10,[char]32) + "`t" + $e.fullname
# Only output entries with a hit count
$cleanOutput = echo $rawOutput | select-string ": 1"
# Remove hit count
$finalOutput = $cleanOutput -replace "Count","" -replace ": ",""
# Trim and output
echo $finalOutput.TrimStart()
}
1 Answer 1
Using findstr in PowerShell is superfluous and
not very powershell'ish which is about objects and pipes.
You can directly pipe the raw output of Get-ChildItem
to Select-String
and parse the resulting object for the information you require.
As the size of the file isn't contained in the properties sls
returns:
Context Property
Filename Property
IgnoreCase Property
Line Property
LineNumber Property
Matches Property
Path Property
Pattern Property
You've to append it, either with a calculated property
# Grab user options
$ext = Read-Host -Prompt "Enter extension "
$huntString = Read-Host -Prompt "Enter hunt string "
Get-ChildItem *.$ext -Recurse | Select-String $huntString -List |
Select-Object @{Label='Size';Expression={(Get-Item $_.Path).Length}},Path
or iterate the output and build a [PSCustomObject]
:
Get-ChildItem *.$ext -Recurse | Select-String $huntString -List |
ForEach-Object {
[PSCustomObject]@{
Path = $_.Path
Size = (Get-Item $_.path).Length
}
}
The objects
output will be the very same:
> Q:\Test2018円12円17円\CR_209811.ps1
Enter extension : ps1
Enter hunt string : ::Now
Size Path
---- ----
878 Q:\Test2018円09円18円\SO_52381514.ps1
677 Q:\Test2018円11円16円\SO_53336923.ps1
770 Q:\Test2018円11円19円\SO_53381881.ps1
1141 Q:\Test2018円12円17円\CR_209811.ps1
1259 Q:\Test2018円12円17円\SU_1385185.ps1
-
1\$\begingroup\$ @RobbieDee Sorry for the missing closing brackets, Label or Name are both valid for calculated properties \$\endgroup\$LotPings– LotPings2018年12月18日 13:12:34 +00:00Commented Dec 18, 2018 at 13:12