2
\$\begingroup\$

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()
}
asked Dec 17, 2018 at 9:10
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

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 objectsoutput 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
answered Dec 17, 2018 at 16:30
\$\endgroup\$
1
  • 1
    \$\begingroup\$ @RobbieDee Sorry for the missing closing brackets, Label or Name are both valid for calculated properties \$\endgroup\$ Commented Dec 18, 2018 at 13:12

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.