`bfs` ===== Version License CI Status Code coverage ***Breadth-first search for your files.*** **[Features]   •   [Installation]   •   [Usage]   •   [Building]   •   [Hacking]   •   [Changelog]** [Features]: #features [Installation]: #installation [Usage]: /docs/USAGE.md [Building]: /docs/BUILDING.md [Hacking]: /docs/HACKING.md [Changelog]: /docs/CHANGELOG.md Screencast

`bfs` is a variant of the UNIX `find` command that operates [**breadth-first**](https://en.wikipedia.org/wiki/Breadth-first_search) rather than [**depth-first**](https://en.wikipedia.org/wiki/Depth-first_search). It is otherwise compatible with many versions of `find`, including
**[POSIX]   •   [GNU]   •   [FreeBSD]   •   [OpenBSD]   •   [NetBSD]   •   [macOS]** [POSIX]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html [GNU]: https://www.gnu.org/software/findutils/ [FreeBSD]: https://www.freebsd.org/cgi/man.cgi?find(1) [OpenBSD]: https://man.openbsd.org/find.1 [NetBSD]: https://man.netbsd.org/find.1 [macOS]: https://ss64.com/osx/find.html
If you're not familiar with `find`, the [GNU find manual](https://www.gnu.org/software/findutils/manual/html_mono/find.html) provides a good introduction. Features --------
bfs operates breadth-first, which typically finds the file(s) you're looking for faster.

Imagine the following directory tree:
haystack
├── deep
│   └── 1
│       └── 2
│           └── 3
│               └── 4
│                   └── ...
└── shallow
    └── needle
`find` will explore the entire `deep` directory tree before it ever gets to the `shallow` one that contains what you're looking for. On the other hand, `bfs` lists files from shallowest to deepest, so you never have to wait for it to explore an entire unrelated subtree.
bfsfind
```console $ find haystack haystack haystack/deep haystack/deep/1 haystack/deep/1/2 haystack/deep/1/2/3 haystack/deep/1/2/3/4 ... haystack/shallow haystack/shallow/needle ``` ```console $ bfs haystack haystack haystack/deep haystack/shallow haystack/deep/1 haystack/shallow/needle ... ```
bfs tries to be easier to use than find, while remaining compatible.

For example, `bfs` is less picky about where you put its arguments:
bfsfind
```console $ bfs -L -name 'needle' haystack haystack/needle $ bfs haystack -L -name 'needle' haystack/needle $ bfs -L haystack -name 'needle' haystack/needle ``` ```console $ find -L -name 'needle' haystack find: paths must precede expression: haystack $ find haystack -L -name 'needle' find: unknown predicate `-L' $ find -L haystack -name 'needle' haystack/needle ```
bfs gives helpful errors and warnings.

For example, `bfs` will detect and suggest corrections for typos: ```console $ bfs -nam needle bfs: error: bfs -nam needle bfs: error: ~~~~ bfs: error: Unknown argument; did you mean -name? ``` `bfs` also includes a powerful static analysis to help catch mistakes: ```console $ bfs -print -name 'needle' bfs: warning: bfs -print -name needle bfs: warning: ~~~~~~~~~~~~ bfs: warning: The result of this expression is ignored. ```
bfs adds some options that make common tasks easier.

For example, the `-exclude` operator skips over entire subtrees whenever an expression matches. `-exclude` is both more powerful and easier to use than the standard `-prune` action; compare
$ bfs -name config -exclude -name .git
to the equivalent
$ find ! \( -name .git -prune \) -name config
As an additional shorthand, `-nohidden` skips over all hidden files and directories. See the [usage documentation](/docs/USAGE.md#extensions) for more about the extensions provided by `bfs`.
Installation ------------
bfs may already be packaged for your operating system.

Alpine Linux
# apk add bfs

Arch Linux
(Available in the AUR)

Debian/Ubuntu
# apt install bfs

Fedora Linux
# dnf install bfs

NixOS
# nix-env -i bfs

Void Linux
# xbps-install -S bfs

FreeBSD
# pkg install bfs

MacPorts
# port install bfs

Homebrew
$ brew install tavianator/tap/bfs
To build bfs from source, you may need to install some dependencies.

The only absolute requirements for building `bfs` are a C compiler, [GNU make](https://www.gnu.org/software/make/), and [Bash](https://www.gnu.org/software/bash/). These are installed by default on many systems, and easy to install on most others. Refer to your operating system's documentation on building software. `bfs` also depends on some system libraries for some of its features. Here's how to install them on some common platforms:
Alpine Linux
# apk add acl{,-dev} attr{,-dev} libcap{,-dev} oniguruma-dev

Arch Linux
# pacman -S acl attr libcap oniguruma

Debian/Ubuntu
# apt install acl libacl1-dev attr libattr1-dev libcap2-bin libcap-dev libonig-dev

Fedora
# dnf install libacl-devel libattr-devel libcap-devel oniguruma-devel

NixOS
# nix-env -i acl attr libcap oniguruma

Void Linux
# xbps-install -S acl-{devel,progs} attr-{devel,progs} libcap-{devel,progs} oniguruma-devel

FreeBSD
# pkg install oniguruma

MacPorts
# port install oniguruma6

Homebrew
$ brew install oniguruma
These dependencies are technically optional, though strongly recommended. See the [build documentation](/docs/BUILDING.md#dependencies) for how to disable them.
Once you have the dependencies, you can build bfs.

Download one of the [releases](https://github.com/tavianator/bfs/releases) or clone the [git repo](https://github.com/tavianator/bfs). Then run $ make This will build the `./bin/bfs` binary. Run the test suite to make sure it works correctly: $ make check If you're interested in speed, you may want to build the release version instead: $ make release Finally, if you want to install it globally, run # make install