72

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]
0

10 Answers 10

44
dir <drive: [drive:]> /s | findstr /i <pattern>

- alternative -

dir /s <drive:>\<pattern>

example

dir c: d: /s | findstr /i example.txt

- alternative -

dir /s c:\example.txt
5
  • dir c: /s example.txt works, too.
    – DevSolar
    Jun 25, 2012 at 11:55
  • @DevSolar can you recheck your command? I've tested it on Windows 5.1 Build 2600 SP3, and your command just gives me the list of files in the directory c:
    – JohannesM
    Jun 25, 2012 at 12:07
  • 2
    Uh... sorry. Serves me right to type from memory. dir /s C:\example.txt it is.
    – DevSolar
    Jun 25, 2012 at 12:14
  • 1
    for the most similar results I use \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, 2015 at 3:51
  • 2
    adding \B to \S allows to have a more terse output, with 1 file per line with full path,, no headers, no size info, etc... Apr 23, 2020 at 8:06
40

With no additional cmdlets installed, you can simply use Get-ChildItem:

Get-ChildItem -Filter *.zip -Recurse $pwd
1
  • 6
    In which case you probably want to use one of the short aliases dir, ls or gci, unless you are writing a script.
    – user776768
    Aug 31, 2018 at 7:14
28

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

  1. Find-ChildItem -Type f -Name ".*.exe"
  2. Find-ChildItem -Type f -Name "\.c$" -Exec "Get-Content {} | Measure-Object -Line -Character -Word"
  3. Find-ChildItem -Type f -Empty
  4. Find-ChildItem -Type f -Empty -OutObject
  5. Find-ChildItem -Type f -Empty -Delete
  6. Find-ChildItem -Type f -Size +9M -Delete
  7. Find-ChildItem -Type d
  8. Find-ChildItem -Type f -Size +50m -WTime +5 -MaxDepth 1 -Delete

Disclosure: I am the developer of Find-ChildItem cmdlet

4
  • 2
    Thank you. This is definitely more in mind of what I'd be looking for in answering this question. Feb 2, 2015 at 16:37
  • 31
    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, 2018 at 13:49
  • @jagadish-g A bloody shame it's not already been integrated to PS long time ago. Did you try to file a PR in the powershell github repo.
    – not2qubit
    Apr 29, 2020 at 22:15
  • 1
    ...and link is dead.
    – not2qubit
    Sep 25, 2020 at 19:51
8

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.

3

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 .
1
  • Find -exec grep {} from UnixUtils doesn't work properly it seems "no such file or directory". This solution: PowerShell.exe -Command "dir -Recurse -ea 0 | ? FullName -like '*.log' | sls error", from within a batch script works. Note: must use single quotes inside, double quotes outside.
    – Kevin
    Nov 6, 2018 at 16:18
2

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: $_"
}
1
  • I think that's by far the best answer.` (ls -r).FullName is basically the same es a simple find in Linux. Jan 27, 2023 at 12:56
1
ls c:\ file.ext -r

You can use this simple powershell command. use -ErrorAction Ignore to get rid of permission errors.

1
  • 1
    I like the simplicity. Adding -name makes it an even simpler listing of names only.
    – Noumenon
    Jan 31, 2021 at 17:39
1

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
0

You can use get-childitem very similar to find.

get-childitem -recurse [startpath] -name [filetofind]

[startpath] is the path where recursion should begin (e.g. . for the current directory)

[filetofind] is what you are looking for.

It is even possible to do this from cmd (without interactieve powershell):

powershell -command "get-childitem -recurse [startpath] -name [filetofind]"
0

On Windows you can use Windows Subsystem for Linux (WSL), install a Linux VM like Debian or Ubuntu. Then you have the C-disk available under /mnt/c.

find /mnt/c/ -name [filename]

You can of course cd into the directory first.

cd /mnt/c/Users/John/Documents
find . -name [filename]

If I try this last search, I need quotes around the filename, while not when using the absolute path.

2
  • 1
    I thought the S of WSL stood for "Subsystem" not "Sublayer"?
    – AJM
    Feb 6 at 13:59
  • 1
    @AJM - You're correct!
    – SPRBRN
    Feb 7 at 15:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .