What is the equivalent of the Unix find command on Windows?
I see that the find.exe
on Windows is more like a grep
. I am especially interested in the equivalent of
find . -name [filename]
Super User is a question and answer site for computer enthusiasts and power users. It only takes a minute to sign up.
Sign up to join this communityWhat is the equivalent of the Unix find command on Windows?
I see that the find.exe
on Windows is more like a grep
. I am especially interested in the equivalent of
find . -name [filename]
dir <drive: [drive:]> /s | findstr /i <pattern>
- alternative -
dir /s <drive:>\<pattern>
dir c: d: /s | findstr /i example.txt
- alternative -
dir /s c:\example.txt
dir /s C:\example.txt
it is.
– DevSolar
Jun 25 '12 at 12:14
\b
for brief (output only paths); find <folder> -name <pattern>
-> dir /s /b <folder><pattern>
. E.g. find /tmp -name *.txt
-> dir \s \b C:\temp\*.txt
. However dir
always returns a list of absolute paths, whereas find
always gives paths prefixed with <folder>
– Hashbrown
May 26 '15 at 3:51
\B
to \S
allows to have a more terse output, with 1 file per line with full path,, no headers, no size info, etc...
– Jean-François Fabre
Apr 23 '20 at 8:06
With no additional cmdlets installed, you can simply use Get-ChildItem
:
Get-ChildItem -Filter *.zip -Recurse $pwd
dir
, ls
or gci
, unless you are writing a script.
– user776768
Aug 31 '18 at 7:14
The Find-ChildItem
Cmdlet in Windows Powershell is an equivalent of Unix/Linux find command
http://windows-powershell-scripts.blogspot.in/2009/08/unix-linux-find-equivalent-in.html
Some of Find-ChildItem Options
Find-ChildItem -Type f -Name ".*.exe"
Find-ChildItem -Type f -Name "\.c$" -Exec "Get-Content {} | Measure-Object -Line -Character -Word"
Find-ChildItem -Type f -Empty
Find-ChildItem -Type f -Empty -OutObject
Find-ChildItem -Type f -Empty -Delete
Find-ChildItem -Type f -Size +9M -Delete
Find-ChildItem -Type d
Find-ChildItem -Type f -Size +50m -WTime +5 -MaxDepth 1 -Delete
Disclosure: I am the developer of Find-ChildItem
cmdlet
Find-ChildItem
is not an official cmdlet and it is not included in PowerShell; you have to download this cmdlet from some guy's OneDrive. There's no difference between that and just downloading bash, cygwin, unixutils or any other program that just lets you run UNIX's find
.
– walen
Apr 18 '18 at 13:49
If you are using Unix's find to search for files in a directory hierarchy, then
the Powershell way is to use Get-ChildItem
(alias is gci
) cmdlet and filter the results with the Where-Object
(alias is where
) cmdlet.
For example, to find all files (starting from C:\Users\
and recursively) with the word 'essential' in its name, use the following:
PS> gci -Path "C:\Users\" -Recurse | where {$_.Name -like '*essential*'}
The -like
option allows you to use wildcards for pattern matching.
This one is not exactly GNU find, but more closely matches the linux command line philisophy under powershell:
PS> dir -recurse -ea 0 | % FullName | sls <grep_string>
Example:
PS> cd C:\
PS> dir -recurse -ea 0 | % FullName | sls "Program" | sls "Microsoft"
PS> dir -recurse -ea 0 | % FullName | sls "Program" | sls "Microsoft" | out-gridview
Note: Everything returned after "| % FullName" is a string, instead of an object.
You can also use the Where Operator, "?", however, its more work, and not much faster:
PS> cd C:\
PS> dir -Recurse -ea 0 | ? FullName -like "*Program*"
| ? FullName -like "*Microsoft*"
| % FullName
| out-gridview
Here's a quick shortcut:
PS> function myfind {dir -recurse -ea 0 | % FullName | sls $args }
PS> cd C:\
PS> myfind "Programs" | sls "Microsoft"
#find all text files recursively from current directory
PS> myfind "\.txt$"
#find all files recursively from current directory
PS> myfind .
ls c:\ file.ext -r
You can use this simple powershell command. use -ErrorAction Ignore to get rid of permission errors.
-name
makes it an even simpler listing of names only.
– Noumenon
Jan 31 at 17:39
In PowerShell you can use Get-ChildItem
(aka ls
), as noted in other answers.
ls . -Filter *.zip -Recurse
It might also be useful to get full paths of files instead of short names.
(ls -Path . -Filter *.zip -Recurse).FullName
And you can also easily execute arbitrary commands on the files found.
(ls -Path . -Filter *.zip -Recurse).FullName | ForEach-Object -Process {
# The $_ variable is the path to a located file.
echo "Found file: $_"
}
While not a full substitute, this simple batch file solved most of the problem for me:
# findw.bat
#
# usage: findw dir search-pattern
#
dir %1 /s /b | findstr /i %2