How to select files that have no extension using powershell
Asked Answered
J

4

5

I have a drive with lots of directories and files, some of which are broken and have no file extension. I would like to delete all of the files that do NOT have an extension. I have tried gci | where {$_.extension -eq ""} and gci | where {$_.extension -eq "."} and variations of those, but end up getting nothing or everything on the drive.

If I look at the results of gci | select Extension the files show nothing for the extension, just like a directory, not sure where to go.

Any help would be appreciated.

Journeywork answered 12/2, 2014 at 20:44 Comment(0)
B
11
gci -File -Recurse | ?{!($_.Extension)}
Barragan answered 12/2, 2014 at 21:18 Comment(2)
Additionally, if you wanna assign some extension commonly to all those extension-less files then just run this: gci -File -Recurse | ?{!($_.Extension)} | Rename-Item -NewName {$_.BaseName + '.<ext>'}, easy peasy!.Fresno
With operator precedence, you don't need the parentheses.Newish
R
9

The simplest and fastest solution (PSv3+) is to use the -Filter parameter:

Get-ChildItem -File -Filter *.

as explained in this answer.

As for a pipeline-based solution:

PowerShell (Core) 7 now offers the -Not switch with the simplified comparison statement syntax that itself was introduced to Where-Object (whose built-in alias is ?) in Windows PowerShell v3, which enables the following, more concise variant of TheMadTechnician's helpful answer:

Get-ChildItem -File | Where-Object -Not Extension

# Alternatively, using built-in alias ? for Where-Object
Get-ChildItem -File | ? -Not Extension

As in TheMadTechnician's answer, this uses implicit Boolean logic: any nonempty string evaluates to $True in a Boolean context, so applying -Not (whose alternative form in expression(-parsing) mode is !) means that $true is only returned if the string is empty, i.e., if the file has no extension.


As for what you tried:

gci | where {$_.extension -eq ""} works in principle, except that it also includes directories.

In PSv3+ you can use the -File switch to limit the results to files, as above.

In PSv2 you must add a condition to the script block, based on the .PSISContainer property only returning $True for directories:

gci | where { -not $_.PSIsContainer -and $_.Extension -eq "" }
Reprobative answered 7/8, 2018 at 16:7 Comment(2)
What a spectacular explanation! Thank you for expanding on my extremely rudimentary answer. I really need to go back and flesh out my earlier answers like the one above (or perhaps below depending on future votes) to improve quality. Though in my defense I had only joined SO 2 weeks before writing that.Barragan
I appreciate the nice feedback, @TheMadTechnician. Yes, the teaching-a-person-to-fish angle is important, in the simplest case with just a link to the docs. Still, a working answer even without explanation is better than none, and I get how it can get tiresome to explain certain things over and over.Reprobative
D
2
ls | where {!$_.PsIsContainer -and ![io.path]::hasextension($_.name) }
Diakinesis answered 12/2, 2014 at 20:50 Comment(0)
N
0

Or

get-childitem * -file -exclude *.*

or

get-childitem -file | ? extension -eq '' # not $null or $false

I wish I could say | ? ! extension, although you can say | ? { ! $_.extension }.

Newish answered 17/10 at 1:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.