How to retrieve recursively any files with a specific extensions in PowerShell?
PowershellPowershell Problem Overview
For a specific folder, I need to list all files with extension .js
even if nested in subfolders at any level.
The result for the output console should be a list of file names with no extension line by line to be easily copy and pasted in another application.
At the moment I am trying this, but in output console I get several meta information and not a simple list.
Get-ChildItem -Path C:\xx\x-Recurse -File | sort length –Descending
Could you please provide me some hints?
Powershell Solutions
Solution 1 - Powershell
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)
Solution 2 - Powershell
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","") }
Solution 3 - Powershell
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
Solution 4 - 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
Solution 5 - Powershell
The above Answers works fine. However in WIndows there is a alias called ls the same as on linux so another shorter command that works too would be ls -Filter *.exe
Solution 6 - Powershell
Use BaseName for the file name without the file extension.
Get-ChildItem -Path ".\*.js" | Sort-Object Length -Descending | ForEach-Object {
$_.BaseName
}
Solution 7 - Powershell
I always used cygwin for this in the past. My last employer locked down our environments and it wasn't available. I like to review the latest files I've modified often. I created the following environment variable named LatestCode to store the script. I then execute it with: iex $env:latest code.
Here is the script: get-childitem “.” -recurse -include *.ts, *.html , *.sass, *.java, *.js, *.css | where-object {$_.mode -notmatch “d”} | sort lastwritetime -descending | Select-Object -First 25 | format-table lastwritetime, fullname -autosize