The Wayback Machine - https://web.archive.org/web/20190311101551/https://github.com/jhspetersson/fselect
Skip to content
Find files with SQL-like queries
Branch: master
Clone or download
Latest commit abd5c92 Mar 10, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
docs add !=~ and NOTLIKE operators #44 Mar 6, 2019
src fix colors on Windows #45 Mar 10, 2019
.gitignore get missing .gitignore file back Feb 1, 2019
.travis.yml Add CI on Windows Oct 11, 2018
Cargo.toml bump version Mar 10, 2019
LICENSE-APACHE add license files Mar 6, 2018
LICENSE-MIT add license files Mar 6, 2018
README.md bump version Mar 10, 2019

README.md

fselect

Find files with SQL-like queries

Crates.io Build Status

Why use fselect?

While it doesn't tend to fully replace traditional find and ls, fselect has these nice features:

  • SQL-like (not real SQL, but highly relaxed!) grammar easily understandable by humans
  • complex queries
  • aggregate, date, and other functions
  • search within archives
  • .gitignore and .hgignore support (experimental)
  • search by width and height of images
  • search by MP3 info
  • search by EXIF metadata
  • search by extended file attributes
  • search by file hashes
  • shortcuts to common file types
  • various output formatting (CSV, JSON, and others)

More is under way!

Installation

From source

  • Install Rust with Cargo and its dependencies to build a binary
  • Run cargo install fselect

Arch Linux

AUR package, thanks to @asm0dey

Other Linux

Static build with musl.

Windows 64bit

A statically precompiled binary is available at Github downloads.

Mac

Precompiled on OS X Mavericks 10.9.5

Mac from brew

  • Install brew
  • Run brew install fselect

Usage

fselect COLUMN[, COLUMN...] [from ROOT[, ROOT...]] [where EXPR] [order by COLUMNS] [limit N] [into FORMAT]

Documentation

More detailed description. Look examples first.

Examples

Find temporary or config files (full path and size):

fselect size, path from /home/user where name = '*.cfg' or name = '*.tmp'

Windows users may omit the quotes:

fselect size, path from C:\Users\user where name = *.cfg or name = *.tmp

Or put all the arguments into the quotes like this:

fselect "name from /home/user/tmp where size > 0"

Find files (just names) with any content (size > 0):

fselect name from /home/user/tmp where size gt 0

Specify file size, get absolute path, and add it to the results:

cd /home/user
fselect size, abspath from ./tmp where size gt 2g
fselect fsize, abspath from ./tmp where size = 5m
fselect hsize, abspath from ./tmp where size lt 8k

More complex query:

fselect "name from /tmp where (name = *.tmp and size = 0) or (name = *.cfg and size > 1000000)"

Aggregate functions:

fselect "MIN(size), MAX(size), AVG(size), SUM(size), COUNT(*) from /home/user/Downloads"

Formatting functions:

fselect "LOWER(name), UPPER(name), LENGTH(name), YEAR(modified) from /home/user/Downloads"

Use single quotes if you need to address files with spaces:

fselect "path from '/home/user/Misc stuff' where name != 'Some file'"

Regular expressions of Rust flavor are supported:

fselect name from /home/user where path =~ '.*Rust.*'

Negate regular expressions:

fselect "name from . where path !=~ '^\./config'"

Simple globs expand automatically and work with = and != operators:

fselect name from /home/user where path = '*Rust*'

Classic LIKE:

fselect "path from /home/user where name like '%report-2018-__-__???'"

Exact match operators to search with regexps disabled:

fselect "path from /home/user where name === 'some_*_weird_*_name'"

Find files by date:

fselect path from /home/user where created = 2017-05-01
fselect path from /home/user where modified = today
fselect path from /home/user where accessed = yesterday
fselect "path from /home/user where modified = 'apr 1'"
fselect "path from /home/user where modified = 'last fri'"

Be more specific to match all files created at interval between 3PM and 4PM:

fselect path from /home/user where created = '2017-05-01 15'

And even more specific:

fselect path from /home/user where created = '2017-05-01 15:10'
fselect path from /home/user where created = '2017-05-01 15:10:30'

Date and time intervals possible (find everything updated since May 1st):

fselect path from /home/user where modified gte 2017-05-01

Default is current directory:

fselect path, size where name = '*.jpg'

Search within multiple locations:

fselect path from /home/user/oldstuff, /home/user/newstuff where name = '*.jpg'

With minimum and/or maximum depth specified (depth is a synonym for maxdepth):

fselect path from /home/user/oldstuff depth 5 where name = '*.jpg'
fselect path from /home/user/oldstuff mindepth 2 maxdepth 5, /home/user/newstuff depth 10 where name = '*.jpg'

Optionally follow symlinks:

fselect path, size from /home/user symlinks where name = '*.jpg'

Search within archives (currently only zip-archives are supported):

fselect path, size from /home/user archives where name = '*.jpg'

Or in combination:

fselect size, path from /home/user depth 5 archives symlinks where name = '*.jpg' limit 100

Enable .gitignore or .hgignore support:

fselect size, path from /home/user/projects gitignore where name = '*.cpp'
fselect size, path from /home/user/projects hgignore where name = '*.py'        

Search by image dimensions:

fselect width, height, path from /home/user/photos where width gte 2000 or height gte 2000

Find square images:

fselect path from /home/user/Photos where width = height

Find old-school rap MP3 files:

fselect path from /home/user/music where genre = Rap and bitrate = 320 and mp3_year lt 2000  

Shortcuts to common file extensions:

fselect path from /home/user where is_archive = true
fselect path from /home/user where is_audio = 1
fselect path from /home/user where is_book != false
fselect path from /home/user where is_doc != 1
fselect path from /home/user where is_image = false
fselect path from /home/user where is_video != true

Find files with dangerous permissions:

fselect mode, path from /home/user where other_write = true or other_exec = true

Simple glob-like expressions or even regular expressions on file mode are possible:

fselect mode, path from /home/user where mode = '*rwx'
fselect mode, path from /home/user where mode =~ '.*rwx$'

Find files by owner's uid or gid:

fselect uid, gid, path from /home/user where uid != 1000 or gid != 1000

Or by owner's or group's name:

fselect user, group, path from /home/user where user = mike or group = mike

Find special files:

fselect name from /usr/bin where suid = true
fselect path from /tmp where is_pipe = true
fselect path from /tmp where is_socket = 1

Find files with xattrs, check if particular xattr exists, or get its value:

fselect "path, has_xattrs, has_xattr(user.test), xattr(user.test) from /home/user"

Include arbitrary text as columns:

fselect "name, ' has size of ', size, ' bytes'"

Order results:

fselect path from /tmp order by size desc, name
fselect modified, fsize, path from ~ order by 1 desc, 3

Finally limit the results:

fselect name from /home/user/samples limit 5 

Format output:

fselect size, path from /home/user limit 5 into json
fselect size, path from /home/user limit 5 into csv
fselect size, path from /home/user limit 5 into html

License

MIT/Apache-2.0

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.