How to retrieve recursively any files with a specific extensions in PowerShell?

If you like brevity, you can remove the ForEach-Object and quotes. -Path defaults to the current directory so you can omit it

(Get-ChildItem -Filter *.js -Recurse).BaseName | Sort length -Descending

There are two methods for filtering files: globbing using an Wildcard, or using a Regular Expression (Regex).

Warning: The globbing method has the drawback that it also matches files which should not be matched, like *.jsx.

# globbing with Wildcard filter 
# the error action prevents the output of errors
# (ie. directory requires admin rights and is inaccessible)
Get-ChildItem -Recurse -Filter '*.js' -ErrorAction 'SilentlyContinue' 

# filter by Regex
Where-Object { $_.Name -Match '.*\.js$' }

You then can sort by name or filesize as needed:

# sort the output 
Sort-Object -PropertyName 'Length'

Format it a simple list of path and filename:

# format output
Format-List -Property ('Path','Name')

To remove the file extension, you can use an select to map the result:

Select-Item { $_.Name.Replace( ".js", "")

Putting it all together, there is also a very short version, which you should not use in scripts, because it's hardly readable:

ls -r | ? { $_.Name -matches '.*\.js' } | sort Length | % { $_.Name.Replace( ".js", "") | fl

If sorting by Length is not a necessity, you can use the -Name parameter to have Get-ChildItem return just the name, then use [System.IO.Path]::GetFileNameWithoutExtension() to remove the path and extension:

Get-ChildItem -Path .\ -Filter *.js -Recurse -File -Name| ForEach-Object {
    [System.IO.Path]::GetFileNameWithoutExtension($_)
}

If sorting by length is desired, drop the -Name parameter and output the BaseName property of each FileInfo object. You can pipe the output (in both examples) to clip, to copy it into the clipboard:

Get-ChildItem -Path .\ -Filter *.js -Recurse -File| Sort-Object Length -Descending | ForEach-Object {
    $_.BaseName
} | clip

If you want the full path, but without the extension, substitute $_.BaseName with:

$_.FullName.Remove($_.FullName.Length - $_.Extension.Length)

The simple option is to use the .Name property of the FileInfo item in the pipeline and then remove the extension:

Get-ChildItem -Path "C:\code\" -Filter *.js -r | % { $_.Name.Replace( ".js","") }

Tags:

Powershell