Search through your filesystem with SQL-esque queries.
Search through your filesystem with SQL-esque queries.
$ go get -u -v github.com/kashav/fsql/... $ which fsql $GOPATH/bin/fsql
$ brew install fsql $ which fsql /usr/local/bin/fsql
$ git clone https://github.com/kashav/fsql.git $GOPATH/src/github.com/kashav/fsql $ cd $_ # $GOPATH/src/github.com/kashav/fsql $ make $ ./fsql
fsql expects a single query via stdin. You may also choose to use fsql in interactive mode.
View the usage dialogue with the
$ fsql -help usage: fsql [options] [query] -v print version and exit (shorthand) -version print version and exit
In general, each query requires a
SELECTclause (to specify which attributes will be shown), a
FROMclause (to specify which directories to search), and a
WHEREclause (to specify conditions to test against).
>>> SELECT attribute, ... FROM source, ... WHERE condition;
You may choose to omit the
If you're providing your query via stdin, quotes are not required, however you'll have to escape reserved characters (e.g.
Currently supported attributes include
*to choose all; if no attribute is provided, this is chosen by default.
Each group features a set of equivalent clauses.
>>> SELECT name, size, time ... >>> name, size, time ...
>>> SELECT all FROM ... >>> all FROM ... >>> FROM ...
Each source should be a relative or absolute path to a directory on your machine.
Source paths may include environment variables (e.g.
$GOPATH) or tildes (
~). Use a hyphen (
-) to exclude a directory. Source paths also support usage of glob patterns.
In the case that a directory begins with a hyphen (e.g.
-foo), use the following to include it as a source:
>>> ... FROM ./-foo ...
>>> ... FROM . ...
>>> ... FROM ~/Desktop, ./*/**.go ...
>>> ... FROM $GOPATH, -.git/ ...
A single condition is made up of 3 parts: an attribute, an operator, and a value.
A valid attribute is any of the following:
Each attribute has a set of associated operators.
| Operator | Description | | :---: | --- | |
=| String equality | |
!=| Synonymous to using
"NOT ... = ..."| |
IN| Basic list inclusion | |
LIKE| Simple pattern matching. Use
%to match zero, one, or multiple characters. Check that a string begins with a value:
%, ends with a value:
%, or contains a value:
%%. | |
RLIKE| Pattern matching with regular expressions. |
If the value contains spaces, wrap the value in quotes (either single or double) or backticks.
The default unit for
The default format for
MMM DD YYYY HH MM(e.g.
"Jan 02 2006 15 04").
modeto test if a file is regular (
IS REG) or if it's a directory (
hashto compute and/or compare the hash value of a file. The default algorithm is
ORto join conditions. Note that precedence is assigned based on order of appearance.
WHERE a AND b OR cis not the same as
WHERE c OR b AND a. Use parentheses to get around this behaviour, i.e.
WHERE a AND b OR cis the same as
WHERE c OR (b AND a).
>>> ... WHERE name = main.go OR size = 5 ...
>>> ... WHERE name = main.go AND size > 20 ...
NOTto negate a condition. This keyword must precede the condition (e.g.
... WHERE NOT a ...).
Note that negating parenthesized conditions is currently not supported. However, this can easily be resolved by applying De Morgan's laws to your query. For example,
... WHERE NOT (a AND b) ...is logically equivalent to
... WHERE NOT a OR NOT b ...(the latter is actually more optimal, due to lazy evaluation).
>>> ... WHERE NOT name = main.go ...
Attribute modifiers are used to specify how input and output values should be processed. These functions are applied directly to attributes in the
The table below lists currently-supported modifiers. Note that the first parameter to
FORMATis always the attribute name.
| Attribute | Modifier | Supported in
SELECT| Supported in
WHERE| | :---: | --- | :---: | :---: | |
SHA1(, n)| ✔️ | ✔️ | |
FORMAT(, UPPER)) | ✔️ | ✔️ | | |
FORMAT(, LOWER)) | ✔️ | ✔️ | | |
FULLPATH| ✔️ | | | |
SHORTPATH| ✔️ | | |
FORMAT(, unit)| ✔️ | ✔️ | |
FORMAT(, layout)| ✔️ | ✔️ |
Specify the length of the hash value. Use a negative integer or
ALLto display all digits.
Specify the size unit. One of:
UNIX, or custom. Custom layouts must be provided in reference to the following date:
Mon Jan 2 15:04:05 -0700 MST 2006.
>>> SELECT SHA1(hash, 20) ...
>>> ... WHERE UPPER(name) ...
>>> SELECT FORMAT(size, MB) ...
>>> ... WHERE FORMAT(time, "Mon Jan 2 2006 15:04:05") ...
Subqueries allow for more complex condition statements. These queries are recursively evaluated while parsing. SELECTing multiple attributes in a subquery is not currently supported; if more than one attribute (or
all) is provided, only the first attribute is used.
Support for referencing superqueries is not yet implemented, see #4 if you'd like to help with this.
>>> ... WHERE name IN (SELECT name FROM ../foo) ...
List all attributes of each directory in your home directory (note the escaped
$ fsql SELECT \* FROM ~ WHERE mode IS DIR
List the names of all files in the Desktop and Downloads directory that contain
cscin the name:
$ fsql "SELECT name FROM ~/Desktop, ~/Downloads WHERE name LIKE %csc%"
List all files in the current directory that are also present in some other directory:
$ fsql >>> SELECT all FROM . WHERE name IN ( ... SELECT name FROM ~/Desktop/files.bak/ ... );
Passing queries via stdin without quotes is a bit of a pain, hopefully the next examples highlight that, my suggestion is to use interactive mode or wrap the query in quotes if you're doing anything with subqueries or attribute modifiers.
List all files named
$GOPATHwhich are larger than 10.5 kilobytes or smaller than 100 bytes:
$ fsql SELECT all FROM $GOPATH WHERE name = main.go AND \(FORMAT\(size, KB\) \>= 10.5 OR size \< 100\) $ fsql "SELECT all FROM $GOPATH WHERE name = main.go AND (FORMAT(size, KB) >= 10.5 OR size < 100)" $ fsql >>> SELECT ... all ... FROM ... $GOPATH ... WHERE ... name = main.go ... AND ( ... FORMAT(size, KB) >= 10.5 ... OR size < 100 ... ) ... ;
$ fsql SELECT UPPER\(name\), FORMAT\(size, KB\), FORMAT\(time, ISO\) FROM . WHERE name LIKE %.js AND time \> \'Apr 01 2017 00 00\' $ fsql "SELECT UPPER(name), FORMAT(size, KB), FORMAT(time, ISO) FROM . WHERE name LIKE %.js AND time > 'Apr 01 2017 00 00'" $ fsql >>> SELECT ... UPPER(name), ... FORMAT(size, KB), ... FORMAT(time, ISO) ... FROM ... . ... WHERE ... name LIKE %.js ... AND time > 'Apr 01 2017 00 00' ... ;
Before submitting code, please ensure that tests are passing and the linter is happy. The following commands may be of use, refer to the Makefile to see what they do.
$ make install \ get-tools $ make fmt \ vet \ lint $ make test \ coverage $ make bootstrap-dist \ dist
fsql source code is available under the MIT license.