A file finding utility patterned after Linux find.
npm i find-plus
import { find } from 'find-plus' // ESM
// const { find } = require('find-plus') // CJS
const isaTXTFile = (f) => f.name.endsWith('.txt')
const files = await find({ onlyFiles: true, root: process.env.HOME, tests: [isaTXTFile] }
console.log(`You have ${files.length} text files under your home directory.`)
find()
takes the following options (only the root
option is required):
root
: (required, string) the path from which to begin the search.noTraverseFailed
: (boolean, default:false
) by default,find
will traverse directories even if the directories themselves are not included in the results (e.g., whenonlyFiles
is set totrue
). WhennoTraverseFailed
istrue
, then directories which fail the requirements are not traversed.noTraverseFailed
cannot be combined withnoDirs
or any of theonly
-options exceptonlyDirs
because then the search would be trivially empty.sort
: (string, default: 'breadth') specifies the sort to apply to the results. Possible options are 'breadth', 'depth', 'alpha', and 'none'. The 'none' option returns the order in which the files were discovered on disk and is primarily useful to speed things slightly when you don't care about the order.tests
: (array of functions, default:[]
) an array of functions which take(dirEnt, depth)
; each test function must returntrue
for a file to be considered in the results. Or-ed tests must be implemented in a single function.dirEnt
is afs.DirEnt
-like* object (may be aDirEnt
or modifiedfs.Stats
withname
andpath
properties added) anddepth
is the depth of the file relative to the root (which is depth 0). Thetests
are executed after all the built in tests (likeatDepth
,paths
,onlyFiles
, etc.) have been passed. This limits the range of inputs the customtests
need to deal with.
*: In Node 19.x, DirEnt
s lack the path
field, but we normalize all DirEnt
s to include this field in all versions.
Path matching uses glob style pattern matching provided by minimatch. The "path" matched against is the full path, which differs from the dirEnt.path
which lacks the file basename (dirEnt.name
). In addition, directories are suffixed with the file system seperator. E.g., /users/jane/
, which would match the path **/jane/**
(which would fail without the trailing '/').
Globbing basics:
- *: matches any string or nothing except '/' (file separator)
- **: matches any string or nothing
- ?: matches one character or nothing
- [abc]: matches one of the characters
- [a-z]: matches a character range
- [[:alpha:]]: matches a POSIX character class
- {a,b}: matches one of the patterns, separated by commas, equivalent to '@(a|b)'
- ?(a|b): matches zero or one of the patterns, separated by pipes
- *(a|b): matches zero or more of the patterns
- +(a|b): matches one or more of the patterns
- @(a|b): matches exactly one of the patterns
- !(a|b): matches anything except the patterns
The 'or' constructs can be combined with other special patterns; e.g., '+([abc])' would match 'abccba'.
excludePaths
: (array of strings) any files with a path matching an excluded path are excluded from the results.paths
: (array of strings) a file path must match each path to be included in the results.
atDepth
: (boolean, default:false
) iftrue
, then limits the results to those atdepth
.depth
: (int, default:undefined
) will only descend 'depth' directories past the searchroot
(which is depth 0). Negatvie values are equivalent to 0.excludeRoot
: (boolean, default:false
) iftrue
, thenroot
is excluded from the search results.
The following options default to false
and may be set true
to exclude the particular type of file. Setting all the regular no
-options to true
will raise an error as the search would be trivially empty.
noBlockDevices
,noCharacterDevices
,noDirs
,noFIFOs
,noFiles
,noSockets
,noSpecial
: equivalent tonoBlockDevcies
,noCharacterDevices
,noFIFOs
, andnoSockets
,noSymbolicLinks
The following options default to false
and may be set 'true' to include only the particular type of file. Setting more than one only
-option to true
will raise an error as the search would be trivially empty.
onlyBlockDevices
,onlyCharacterDevices
,onlyDirs
,onlyFIFOs
,onlyFiles
,onlySockets
,onlySymbolicLinks