summaryrefslogtreecommitdiffstats
path: root/docs/USAGE.md
blob: 9f76f1605a056013f2643d0947050ee5066455df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
Using `bfs`
===========

`bfs` has the same command line syntax as `find`, and almost any `find` command that works with a major `find` implementation will also work with `bfs`.
When invoked with no arguments, `bfs` will list everything under the current directory recursively, breadth-first:

```console
$ bfs
.
./LICENSE
./Makefile
./README.md
./completions
./docs
./src
./tests.sh
./tests
./completions/bfs.bash
./completions/bfs.zsh
./docs/BUILDING.md
./docs/CHANGELOG.md
./docs/HACKING.md
./docs/USAGE.md
./docs/bfs.1
./src/bfs.h
...
```


Paths
-----

Arguments that don't begin with `-` are treated as paths to search.
If one or more paths are specified, they are used instead of the current directory:

```console
$ bfs /usr/bin /usr/lib
/usr/bin
/usr/lib
/usr/bin/bfs
...
/usr/lib/libc.so
...
```


Expressions
-----------

Arguments that start with `-` form an *expression* which `bfs` evaluates to filter the matched files, and to do things with the files that match.
The most common expression is probably `-name`, which matches filenames against a glob pattern:

```console
$ bfs -name '*.md'
./README.md
./docs/BUILDING.md
./docs/CHANGELOG.md
./docs/HACKING.md
./docs/USAGE.md
```

### Operators

When you put multiple expressions next to each other, both of them must match:

```console
$ bfs -name '*.md' -name '*ING*'
./docs/BUILDING.md
./docs/HACKING.md
```

This works because the expressions are implicitly combined with *logical and*.
You could be explicit by writing

```console
$ bfs -name '*.md' -and -name '*ING'`
```

There are other operators like `-or`:

```console
$ bfs -name '*.md' -or -name '*.sh'
./README.md
./tests.sh
./tests/find-color.sh
./tests/ls-color.sh
./tests/remove-sibling.sh
./tests/sort-args.sh
./docs/CHANGELOG.md
./docs/HACKING.md
./docs/BUILDING.md
./docs/USAGE.md
```

and `-not`:

```console
$ bfs -name '*.md' -and -not -name '*ING*'
./README.md
./docs/CHANGELOG.md
./docs/USAGE.md
```

### Actions

Every `bfs` expression returns either `true` or `false`.
For expressions like `-name`, that's all they do.
But some expressions, called *actions*, have other side effects.

If no actions are included in the expression, `bfs` adds the `-print` action automatically, which is why the above examples actually print any output.
The default `-print` is supressed if any actions are given explicitly.
Available actions include printing with alternate formats (`-ls`, `-printf`, etc.), executing commands (`-exec`, `-execdir`, etc.), deleting files (`-delete`), and stopping the search (`-quit`, `-exit`).


Extensions
----------

`bfs` implements a few extensions not found in other `find` implementations.

### `-exclude`

The `-exclude` operator skips an entire subtree whenever an expression matches.
For example, `-exclude -name .git` will exclude any files or directories named `.git` from the search results.
`-exclude` is easier to use than the standard `-prune` action; compare

    bfs -name config -exclude -name .git

to the equivalent

    find ! \( -name .git -prune \) -name config

Unlike `-prune`, `-exclude` even works in combination with `-depth`/`-delete`.

---

### `-hidden`/`-nohidden`

`-hidden` matches "hidden" files (dotfiles).
`bfs -hidden` is effectively shorthand for

    find \( -name '.*' -not -name . -not -name .. \)

`-nohidden` is equivalent to `-exclude -hidden`.

---

### `-unique`

This option ensures that `bfs` only visits each file once, even if it's reachable through multiple hard or symbolic links.
It's particularly useful when following symbolic links (`-L`).

---

### `-color`/`-nocolor`

When printing to a terminal, `bfs` automatically colors paths like GNU `ls`, according to the `LS_COLORS` environment variable.
The `-color` and `-nocolor` options override the automatic behavior, which may be handy when you want to preserve colors through a pipe:

    bfs -color | less -R

If the [`NO_COLOR`](https://no-color.org/) environment variable is set, colors will be disabled by default.