README.md
1# fselect
2Find files with SQL-like queries
3
4[![Crates.io](https://img.shields.io/crates/v/fselect.svg)](https://crates.io/crates/fselect)
5[![Build Status](https://travis-ci.org/jhspetersson/fselect.svg?branch=master)](https://travis-ci.org/jhspetersson/fselect)
6
7### Why use fselect?
8
9While it doesn't tend to fully replace traditional `find` and `ls`, **fselect** has these nice features:
10
11* SQL-like (not real SQL, but highly relaxed!) grammar easily understandable by humans
12* complex queries
13* aggregate, statistics, date, and other functions
14* search within archives
15* `.gitignore`, `.hgignore`, and `.dockerignore` support (experimental)
16* search by width and height of images, EXIF metadata
17* search by MP3 info
18* search by extended file attributes
19* search by file hashes
20* search by MIME type
21* shortcuts to common file types
22* interactive mode
23* various output formatting (CSV, JSON, and others)
24
25More is under way!
26
27### Installation
28
29#### Latest release from source
30
31* Install [Rust with Cargo](https://www.rust-lang.org/en-US/install.html) and its dependencies to build a binary
32* Run `cargo install fselect`
33
34#### Arch Linux
35
36[AUR package](https://aur.archlinux.org/packages/fselect/), thanks to [@asm0dey](https://github.com/asm0dey)
37
38#### NixOS
39
40[`fselect` in `nixpkgs`](https://github.com/filalex77/nixpkgs/blob/1eced92263395896c10cea69e5f60e8be5f43aeb/pkgs/tools/misc/fselect/default.nix), thanks to [@filalex77](https://github.com/filalex77)
41
42#### Other Linux
43
44[Static build with musl](https://github.com/jhspetersson/fselect/releases/download/0.7.7/fselect-x86_64-linux-musl.gz).
45
46#### Windows 64bit
47
48A statically precompiled [binary](https://github.com/jhspetersson/fselect/releases/download/0.7.7/fselect-x86_64-win.zip) is available at Github downloads.
49
50#### Windows from Chocolatey
51
52* Install [Chocolatey](https://chocolatey.org/install)
53* Run `choco install fselect`
54
55#### Mac via Homebrew
56
57* Install [brew](https://brew.sh)
58* Run `brew install fselect`
59
60#### Mac via MacPorts
61
62* Install [MacPorts](https://www.macports.org)
63* Run:
64 ```
65 sudo port selfupdate
66 sudo port install fselect
67 ```
68
69### Usage
70
71 fselect [ARGS] COLUMN[, COLUMN...] [from ROOT[, ROOT...]] [where EXPR] [order by COLUMNS] [limit N] [into FORMAT]
72
73### Interactive mode
74
75 fselect -i
76
77### Documentation
78
79[More detailed description. Look at examples first.](docs/usage.md)
80
81### Examples
82
83Find temporary or config files (full path and size):
84
85 fselect size, path from /home/user where name = '*.cfg' or name = '*.tmp'
86
87Windows users may omit the quotes:
88
89 fselect size, path from C:\Users\user where name = *.cfg or name = *.tmp
90
91Or put all the arguments into the quotes like this:
92
93 fselect "name from /home/user/tmp where size > 0"
94
95Find files (just names) with any content (size > 0):
96
97 fselect name from /home/user/tmp where size gt 0
98
99Specify file size, get absolute path, and add it to the results:
100
101 cd /home/user
102 fselect size, abspath from ./tmp where size gt 2g
103 fselect fsize, abspath from ./tmp where size = 5m
104 fselect hsize, abspath from ./tmp where size lt 8k
105
106More complex query:
107
108 fselect "name from /tmp where (name = *.tmp and size = 0) or (name = *.cfg and size > 1000000)"
109
110Aggregate functions:
111
112 fselect "MIN(size), MAX(size), AVG(size), SUM(size), COUNT(*) from /home/user/Downloads"
113
114Formatting functions:
115
116 fselect "LOWER(name), UPPER(name), LENGTH(name), YEAR(modified) from /home/user/Downloads"
117
118Get the year of an oldest file:
119
120 fselect "MIN(YEAR(modified)) from /home/user"
121
122Use single quotes if you need to address files with spaces:
123
124 fselect "path from '/home/user/Misc stuff' where name != 'Some file'"
125
126Regular expressions of [Rust flavor](https://docs.rs/regex/1.1.0/regex/#syntax) are supported:
127
128 fselect name from /home/user where path =~ '.*Rust.*'
129
130Negate regular expressions:
131
132 fselect "name from . where path !=~ '^\./config'"
133
134Simple globs expand automatically and work with `=` and `!=` operators:
135
136 fselect name from /home/user where path = '*Rust*'
137
138Classic LIKE:
139
140 fselect "path from /home/user where name like '%report-2018-__-__???'"
141
142Exact match operators to search with regexps disabled:
143
144 fselect "path from /home/user where name === 'some_*_weird_*_name'"
145
146Find files by date:
147
148 fselect path from /home/user where created = 2017-05-01
149 fselect path from /home/user where modified = today
150 fselect path from /home/user where accessed = yesterday
151 fselect "path from /home/user where modified = 'apr 1'"
152 fselect "path from /home/user where modified = 'last fri'"
153
154Be more specific to match all files created at interval between 3PM and 4PM:
155
156 fselect path from /home/user where created = '2017-05-01 15'
157
158And even more specific:
159
160 fselect path from /home/user where created = '2017-05-01 15:10'
161 fselect path from /home/user where created = '2017-05-01 15:10:30'
162
163Date and time intervals possible (find everything updated since May 1st):
164
165 fselect path from /home/user where modified gte 2017-05-01
166
167Default is current directory:
168
169 fselect path, size where name = '*.jpg'
170
171Search within multiple locations:
172
173 fselect path from /home/user/oldstuff, /home/user/newstuff where name = '*.jpg'
174
175With minimum and/or maximum depth specified (`depth` is a synonym for `maxdepth`):
176
177 fselect path from /home/user/oldstuff depth 5 where name = '*.jpg'
178 fselect path from /home/user/oldstuff mindepth 2 maxdepth 5, /home/user/newstuff depth 10 where name = '*.jpg'
179
180Optionally follow symlinks:
181
182 fselect path, size from /home/user symlinks where name = '*.jpg'
183
184Search within archives (currently only zip-archives are supported):
185
186 fselect path, size from /home/user archives where name = '*.jpg'
187
188Or in combination:
189
190 fselect size, path from /home/user depth 5 archives symlinks where name = '*.jpg' limit 100
191
192Enable `.gitignore` or `.hgignore` support:
193
194 fselect size, path from /home/user/projects gitignore where name = '*.cpp'
195 fselect size, path from /home/user/projects hgignore where name = '*.py'
196
197Search by image dimensions:
198
199 fselect CONCAT(width, 'x', height), path from /home/user/photos where width gte 2000 or height gte 2000
200
201Find square images:
202
203 fselect path from /home/user/Photos where width = height
204
205Find old-school rap MP3 files:
206
207 fselect duration, path from /home/user/music where genre = Rap and bitrate = 320 and mp3_year lt 2000
208
209Shortcuts to common file extensions:
210
211 fselect path from /home/user where is_archive = true
212 fselect path, mime from /home/user where is_audio = 1
213 fselect path, mime from /home/user where is_book != false
214 fselect path from /home/user where is_doc != 1
215 fselect path from /home/user where is_image = false
216 fselect path from /home/user where is_video != true
217
218Find files with dangerous permissions:
219
220 fselect mode, path from /home/user where other_write = true or other_exec = true
221 fselect mode, path from /home/user where other_all = true
222
223Simple glob-like expressions or even regular expressions on file mode are possible:
224
225 fselect mode, path from /home/user where mode = '*rwx'
226 fselect mode, path from /home/user where mode =~ '.*rwx$'
227
228Find files by owner's uid or gid:
229
230 fselect uid, gid, path from /home/user where uid != 1000 or gid != 1000
231
232Or by owner's or group's name:
233
234 fselect user, group, path from /home/user where user = mike or group = mike
235
236Find special files:
237
238 fselect name from /usr/bin where suid = true
239 fselect path from /tmp where is_pipe = true
240 fselect path from /tmp where is_socket = 1
241
242Find files with xattrs, check if particular xattr exists, or get its value:
243
244 fselect "path, has_xattrs, has_xattr(user.test), xattr(user.test) from /home/user"
245
246Include arbitrary text as columns:
247
248 fselect "name, ' has size of ', size, ' bytes'"
249
250Order results:
251
252 fselect path from /tmp order by size desc, name
253 fselect modified, fsize, path from ~ order by 1 desc, 3
254
255Finally limit the results:
256
257 fselect name from /home/user/samples limit 5
258
259Format output:
260
261 fselect size, path from /home/user limit 5 into json
262 fselect size, path from /home/user limit 5 into csv
263 fselect size, path from /home/user limit 5 into html
264
265### License
266
267MIT/Apache-2.0
268
269---
270
271Supported by [JetBrains IDEA](https://www.jetbrains.com/?from=fselect) open source license
272