{"id":13466846,"url":"https://github.com/kashav/fsql","last_synced_at":"2025-05-14T17:05:17.049Z","repository":{"id":50367203,"uuid":"89662045","full_name":"kashav/fsql","owner":"kashav","description":"Search for files using a fun query language","archived":false,"fork":false,"pushed_at":"2024-10-08T06:28:17.000Z","size":5184,"stargazers_count":3996,"open_issues_count":9,"forks_count":120,"subscribers_count":74,"default_branch":"master","last_synced_at":"2025-05-14T17:02:39.204Z","etag":null,"topics":["find","golang"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kashav.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-04-28T03:04:28.000Z","updated_at":"2025-05-12T06:43:17.000Z","dependencies_parsed_at":"2023-07-13T21:45:27.754Z","dependency_job_id":"d909e13e-94c4-4e0c-8956-166d66b5f4b7","html_url":"https://github.com/kashav/fsql","commit_stats":{"total_commits":148,"total_committers":7,"mean_commits":"21.142857142857142","dds":0.05405405405405406,"last_synced_commit":"59480377d1d96bfc35d8774839ed5baee64b7694"},"previous_names":["kshvmdn/fsql"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kashav%2Ffsql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kashav%2Ffsql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kashav%2Ffsql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kashav%2Ffsql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kashav","download_url":"https://codeload.github.com/kashav/fsql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254190396,"owners_count":22029632,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["find","golang"],"created_at":"2024-07-31T15:00:50.672Z","updated_at":"2025-05-14T17:05:17.000Z","avatar_url":"https://github.com/kashav.png","language":"Go","funding_links":[],"categories":["Go","Misc","Go (531)","golang","Tools","CLI Utilities"],"sub_categories":["Go"],"readme":"# fsql [![Go](https://github.com/kashav/fsql/actions/workflows/go.yml/badge.svg)](https://github.com/kashav/fsql/actions/workflows/go.yml)\n\n\u003eSearch through your filesystem with SQL-esque queries.\n\n## Contents\n\n- [Demo](#demo)\n- [Installation](#installation)\n- [Usage](#usage)\n- [Query Syntax](#query-syntax)\n- [Examples](#usage-examples)\n- [Contribute](#contribute)\n- [License](#license)\n\n## Demo\n\n[![fsql.gif](./media/fsql.gif)](https://asciinema.org/a/120534)\n\n## Installation\n\n#### Binaries\n\n[View latest release](https://github.com/kashav/fsql/releases/latest).\n\n#### Via Go\n\n```sh\n$ go get -u -v github.com/kashav/fsql/...\n$ which fsql\n$GOPATH/bin/fsql\n```\n\n#### Via Homebrew\n\n```sh\n$ brew install fsql\n$ which fsql\n/usr/local/bin/fsql\n```\n\n#### Build manually\n\n```sh\n$ git clone https://github.com/kashav/fsql.git $GOPATH/src/github.com/kashav/fsql\n$ cd $_ # $GOPATH/src/github.com/kashav/fsql\n$ make\n$ ./fsql\n```\n\n## Usage\n\nfsql expects a single query via stdin. You may also choose to use fsql in interactive mode.\n\nView the usage dialogue with the `-help` flag.\n\n```sh\n$ fsql -help\nusage: fsql [options] [query]\n  -v  print version and exit (shorthand)\n  -version\n      print version and exit\n```\n\n## Query syntax\n\nIn general, each query requires a `SELECT` clause (to specify which attributes will be shown), a `FROM` clause (to specify which directories to search), and a `WHERE` clause (to specify conditions to test against).\n\n```console\n\u003e\u003e\u003e SELECT attribute, ... FROM source, ... WHERE condition;\n```\n\nYou may choose to omit the `SELECT` and `WHERE` clause.\n\nIf you're providing your query via stdin, quotes are **not** required, however you'll have to escape _reserved_ characters (e.g. `*`, `\u003c`, `\u003e`, etc).\n\n### Attribute\n\nCurrently supported attributes include `name`, `size`, `time`, `hash`, `mode`.\n\nUse `all` or `*` to choose all; if no attribute is provided, this is chosen by default.\n\n**Examples**:\n\nEach group features a set of equivalent clauses.\n\n```console\n\u003e\u003e\u003e SELECT name, size, time ...\n\u003e\u003e\u003e name, size, time ...\n```\n\n```console\n\u003e\u003e\u003e SELECT all FROM ...\n\u003e\u003e\u003e all FROM ...\n\u003e\u003e\u003e FROM ...\n```\n\n### Source\n\nEach source should be a relative or absolute path to a directory on your machine.\n\nSource 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](https://en.wikipedia.org/wiki/Glob_(programming)).\n\nIn the case that a directory begins with a hyphen (e.g. `-foo`), use the following to include it as a source:\n\n```console\n\u003e\u003e\u003e ... FROM ./-foo ...\n```\n\n**Examples**:\n\n```console\n\u003e\u003e\u003e ... FROM . ...\n```\n\n```console\n\u003e\u003e\u003e ... FROM ~/Desktop, ./*/**.go ...\n```\n\n```console\n\u003e\u003e\u003e ... FROM $GOPATH, -.git/ ...\n```\n\n### Condition\n\n#### Condition syntax\n\nA single condition is made up of 3 parts: an attribute, an operator, and a value.\n\n- **Attribute**:\n\n  A valid attribute is any of the following: `name`, `size`, `mode`, `time`.\n\n- **Operator**:\n\n  Each attribute has a set of associated operators.\n\n  - `name`:\n\n    | Operator | Description |\n    | :---: | --- |\n    | `=` | String equality |\n    | `\u003c\u003e` / `!=` | Synonymous to using `\"NOT ... = ...\"` |\n    | `IN` | Basic list inclusion |\n    | `LIKE` |  Simple pattern matching. Use `%` to match zero, one, or multiple characters. Check that a string begins with a value: `\u003cvalue\u003e%`, ends with a value: `%\u003cvalue\u003e`, or contains a value: `%\u003cvalue\u003e%`. |\n    | `RLIKE` | Pattern matching with regular expressions. |\n\n  - `size` / `time`:\n\n    - All basic algebraic operators: `\u003e`, `\u003e=`, `\u003c`, `\u003c=`, `=`, and `\u003c\u003e` / `!=`.\n\n  - `hash`:\n\n    - `=` or `\u003c\u003e` / `!=`\n\n  - `mode`:\n\n    - `IS`\n\n\n- **Value**:\n\n  If the value contains spaces, wrap the value in quotes (either single or double) or backticks.\n\n  The default unit for `size` is bytes.\n\n  The default format for `time` is `MMM DD YYYY HH MM` (e.g. `\"Jan 02 2006 15 04\"`).\n\n  Use `mode` to test if a file is regular (`IS REG`) or if it's a directory (`IS DIR`).\n\n  Use `hash` to compute and/or compare the hash value of a file. The default algorithm is `SHA1`\n\n#### Conjunction / Disjunction\n\nUse `AND` / `OR` to join conditions. Note that precedence is assigned based on order of appearance.\n\nThis means `WHERE a AND b OR c` is **not** the same as `WHERE c OR b AND a`. Use parentheses to get around this behaviour, i.e. `WHERE a AND b OR c` **is** the same as `WHERE c OR (b AND a)`.\n\n**Examples**:\n\n```console\n\u003e\u003e\u003e ... WHERE name = main.go OR size = 5 ...\n```\n\n```console\n\u003e\u003e\u003e ... WHERE name = main.go AND size \u003e 20 ...\n```\n\n#### Negation\n\nUse `NOT` to negate a condition. This keyword **must** precede the condition (e.g. `... WHERE NOT a ...`).\n\nNote that negating parenthesized conditions is currently not supported. However, this can easily be resolved by applying [De Morgan's laws](https://en.wikipedia.org/wiki/De_Morgan%27s_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](https://en.wikipedia.org/wiki/Lazy_evaluation)).\n\n**Examples**:\n\n```console\n\u003e\u003e\u003e ... WHERE NOT name = main.go ...\n```\n\n### Attribute Modifiers\n\nAttribute modifiers are used to specify how input and output values should be processed. These functions are applied directly to attributes in the `SELECT` and `WHERE` clauses.\n\nThe table below lists currently-supported modifiers. Note that the first parameter to `FORMAT` is always the attribute name.\n\n| Attribute | Modifier  | Supported in `SELECT` | Supported in `WHERE` |\n| :---: | --- | :---: | :---: |\n| `hash` | `SHA1(, n)` | ✔️ | ✔️ |\n| `name` | `UPPER` (synonymous to `FORMAT(, UPPER)`) | ✔️ | ✔️ |\n| | `LOWER` (synonymous to `FORMAT(, LOWER)`) | ✔️ | ✔️ |\n| | `FULLPATH` | ✔️ |  |\n| | `SHORTPATH`  | ✔️ |  |\n| `size` | `FORMAT(, unit)` | ✔️ | ✔️ |\n| `time` | `FORMAT(, layout)` | ✔️ | ✔️ |\n\n\n- **`n`**:\n\n  Specify the length of the hash value. Use a negative integer or `ALL` to display all digits.\n\n- **`unit`**:\n\n  Specify the size unit. One of: `B` (byte), `KB` (kilobyte), `MB` (megabyte), or `GB` (gigabyte).\n\n- **`layout`**:\n\n  Specify the time layout. One of: [`ISO`](https://en.wikipedia.org/wiki/ISO_8601), [`UNIX`](https://en.wikipedia.org/wiki/Unix_time), or [custom](https://golang.org/pkg/time/#Time.Format). Custom layouts must be provided in reference to the following date: `Mon Jan 2 15:04:05 -0700 MST 2006`.\n\n**Examples**:\n\n```console\n\u003e\u003e\u003e SELECT SHA1(hash, 20) ...\n```\n\n```console\n\u003e\u003e\u003e ... WHERE UPPER(name) ...\n```\n\n```console\n\u003e\u003e\u003e SELECT FORMAT(size, MB) ...\n```\n\n```console\n\u003e\u003e\u003e ... WHERE FORMAT(time, \"Mon Jan 2 2006 15:04:05\") ...\n```\n\n### Subqueries\n\nSubqueries 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.\n\nSupport for referencing superqueries is not yet implemented, see [#4](https://github.com/kashav/fsql/issues/4) if you'd like to help with this.\n\n**Examples**:\n\n```console\n\u003e\u003e\u003e ... WHERE name IN (SELECT name FROM ../foo) ...\n```\n\n## Usage Examples\n\nList all attributes of each directory in your home directory (note the escaped `*`):\n\n```console\n$ fsql SELECT \\* FROM ~ WHERE mode IS DIR\n```\n\nList the names of all files in the Desktop and Downloads directory that contain `csc` in the name:\n\n```console\n$ fsql \"SELECT name FROM ~/Desktop, ~/Downloads WHERE name LIKE %csc%\"\n```\n\nList all files in the current directory that are also present in some other directory:\n\n```console\n$ fsql\n\u003e\u003e\u003e SELECT all FROM . WHERE name IN (\n...   SELECT name FROM ~/Desktop/files.bak/\n... );\n```\n\nPassing 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.\n\nList all files named `main.go` in `$GOPATH` which are larger than 10.5 kilobytes or smaller than 100 bytes:\n\n```console\n$ fsql SELECT all FROM $GOPATH WHERE name = main.go AND \\(FORMAT\\(size, KB\\) \\\u003e= 10.5 OR size \\\u003c 100\\)\n$ fsql \"SELECT all FROM $GOPATH WHERE name = main.go AND (FORMAT(size, KB) \u003e= 10.5 OR size \u003c 100)\"\n$ fsql\n\u003e\u003e\u003e SELECT\n...   all\n... FROM\n...   $GOPATH\n... WHERE\n...   name = main.go\n...   AND (\n...     FORMAT(size, KB) \u003e= 10.5\n...     OR size \u003c 100\n...   )\n... ;\n```\n\nList the name, size, and modification time of JavaScript files in the current directory that were modified after April 1st 2017:\n\n```console\n$ fsql SELECT UPPER\\(name\\), FORMAT\\(size, KB\\), FORMAT\\(time, ISO\\) FROM . WHERE name LIKE %.js AND time \\\u003e \\'Apr 01 2017 00 00\\'\n$ fsql \"SELECT UPPER(name), FORMAT(size, KB), FORMAT(time, ISO) FROM . WHERE name LIKE %.js AND time \u003e 'Apr 01 2017 00 00'\"\n$ fsql\n\u003e\u003e\u003e SELECT\n...   UPPER(name),\n...   FORMAT(size, KB),\n...   FORMAT(time, ISO)\n... FROM\n...   .\n... WHERE\n...   name LIKE %.js\n...   AND time \u003e 'Apr 01 2017 00 00'\n... ;\n```\n\n## Contribute\n\nThis project is completely open source, feel free to [open an issue](https://github.com/kashav/fsql/issues) or [submit a pull request](https://github.com/kashav/fsql/pulls).\n\nBefore submitting code, please ensure that tests are passing and the linter is happy. The following commands may be of use, refer to the [Makefile](./Makefile) to see what they do.\n\n```sh\n$ make install \\\n       get-tools\n$ make fmt \\\n       vet \\\n       lint\n$ make test \\\n       coverage\n$ make bootstrap-dist \\\n       dist\n```\n\n## License\n\nfsql source code is available under the [MIT license](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkashav%2Ffsql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkashav%2Ffsql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkashav%2Ffsql/lists"}