Skip to content

Latest commit

 

History

History
170 lines (123 loc) · 4.25 KB

File metadata and controls

170 lines (123 loc) · 4.25 KB


Finds files and directories based on different criteria
via an intuitive fluent interface. 👑 Written in Nim language

nimble install find

API reference

Github Actions Github Actions

😍 Key Features

  • Fluent interface for composing search criteria
  • Wildcard name patterns (* and ?) and file-extension filters
  • Regular expressions on the basename or full path
  • Size filters in human-friendly units (B, KB, MB, GB, TB) with ==, !=, <, <=, >, >= operators
  • Content search (literal strings or /regex/) and content exclusion
  • Modification-time filters (modifiedAfter / modifiedBefore)
  • Recursive and non-recursive search
  • Hidden files and directories ignored by default
  • Zero-copy, memory-mapped content scanning
  • Open Source | MIT License
  • Written in Nim language

Usage

Add find to your find.nimble dependencies, then import it:

import find

Quick start

Search a directory for all *.txt files and collect the matches into a seq[string]:

import find

var files: seq[string]
newFinder()
  .path("./examples")
  .name("*.txt")
  .collect(files)

echo files.len # 6

newFinder() defaults to searching for files (fkFile). Use finder() as an alias.

Iterate results

find is also an iterator, yielding each matching path as it is found:

import std/strutils
import find

for path in newFinder().path("./examples").name("*.txt").find():
  echo extractFilename(path)

Filter by file extension

import find

var images: seq[string]
newFinder()
  .path("./examples")
  .ext("jpg") # no leading dot
  .size(< 5.mb)
  .collect(images)
# -> boris-baldinger-eUFfY6cwjSU-unsplash.jpg

Filter by size

import find

# files larger than 2 MB
var big: seq[string]
newFinder().path("./examples").size(> 2.mb).collect(big)

# same, via named helpers
var small: seq[string]
newFinder().path("./examples").largerThan(1.mb).collect(small)

# exact match (empty files)
var empty: seq[string]
newFinder().path("./examples").size(== 0.bytes).collect(empty)

Size helpers: bytes, kb, mb, gb, tb (plus KB, MB, GB, TB). smallerThan works like largerThan with a < rule.

Regular expressions

import std/re
import find

# match the basename
var res: seq[string]
newFinder().path("./examples").namePattern(r"20[\w-]+\.txt").collect(res)

# match the full path
newFinder().path("./examples").pathRegex(r"examples/.+\.md")

Search file contents

import find

# files containing a literal string
var res: seq[string]
newFinder().path("./examples").contains("Lorem").collect(res)

# exclude files containing a string
newFinder().path("./examples").ext("txt").notContains("Lorem")

# a string wrapped in / / is treated as a regular expression
newFinder().path("./examples").contains(r"/Hello\s+World/")

By modification time

import std/times
import find

var recent: seq[string]
newFinder()
  .path("./examples")
  .modifiedAfter(toTime(now() - initDuration(days = 7)))
  .collect(recent)

Search directories

import find

var dirs: seq[string]
newFinder(fkDir).path("./examples").collect(dirs)

fkAny matches every entry kind. Available kinds: fkAny, fkFile, fkDir, fkLinkToFile, fkLinkToDir.

Non-recursive search

import find

newFinder().path("./examples").recursive(false)

For more examples check /tests | API reference

❤ Contributions & Support

🎩 License

Find | MIT license. Made by Humans from OpenPeeps.
Copyright © 2026 George Lemon & Contributors — All rights reserved.