# pick
[](https://crates.io/crates/pick-cli)
[](https://www.npmjs.com/package/@aryanbhosale/pick)
[](https://github.com/aryanbhosale/pick/actions/workflows/ci.yml)
[](LICENSE)
**[pick-cli.pages.dev](https://pick-cli.pages.dev)**
Extract values from anything — JSON, YAML, TOML, .env, HTTP headers, logfmt, CSV, and more.
```bash
cargo install pick-cli
```
`pick` auto-detects the input format and lets you extract, filter, and transform values using a unified selector syntax. Think of it as **jq for all config formats** — no more juggling `jq`, `yq`, `grep`, `awk`, and `cut`.
## Quick Start
```bash
# JSON
# .env
# YAML
# TOML
# HTTP headers
# logfmt
# CSV
```
## Selectors
| `foo` | Top-level key |
| `foo.bar` | Nested key |
| `foo[0]` | Array index |
| `foo[-1]` | Last element |
| `foo[*].name` | All elements, pluck field |
| `foo[1:3]` | Array slice (elements 1 and 2) |
| `foo[:2]` | First 2 elements |
| `foo[-2:]` | Last 2 elements |
| `[0]` | Index into root array |
| `..name` | Recursive descent — find `name` at any depth |
| `"dotted.key".sub` | Quoted key (for keys containing dots) |
| `name, age` | Multiple selectors (union) |
## Pipes & Filters
Chain operations with the pipe operator (`|`), filter with `select()`, and transform with builtins:
```bash
# Filter: find expensive items
cat data.json | pick 'items[*] | select(.email ~ "@gmail\\.com$") | name'
# Boolean logic: and, or, not
cat config.json | pick 'keys()'
cat config.json | pick 'dependencies | length()'
cat data.json | pick 'items[*].name | length()'
# Chain multiple stages
Convert between formats with `--output`:
```bash
# JSON to YAML
# JSON to TOML
# Always output JSON
## Streaming (JSONL)
Process newline-delimited JSON (JSONL) line-by-line with `--stream`:
```bash
# Extract from each line
# Filter streamed data
# Stream from file
pick -f events.jsonl 'timestamp' --stream
```
## Flags
| `-i, --input <format>` | Force input format (`json`, `yaml`, `toml`, `env`, `headers`, `logfmt`, `csv`, `text`) |
| `-o, --output <format>` | Output format (`json`, `yaml`, `toml`) |
| `-f, --file <path>` | Read from file instead of stdin |
| `--json` | Output result as JSON |
| `--raw` | Output without trailing newline |
| `-1, --first` | Only output first result |
| `--lines` | Output array elements one per line |
| `-d, --default <value>` | Default value if selector doesn't match |
| `-q, --quiet` | Suppress error messages |
| `-e, --exists` | Check if selector matches (exit code only) |
| `-c, --count` | Output count of matches |
| `--stream` | Stream mode: process JSONL input line-by-line |
## Examples
### Pipe-friendly
```bash
# Get the current git user's repos
if cat config.json | pick database.host --exists; then
DB_HOST=$(cat config.json | pick database.host)
fi
# Extract with a fallback
# Count results
| JSON | Yes | `{"key": "value"}` |
| YAML | Yes | `key: value` |
| TOML | Yes | `[section]` / `key = "value"` |
| .env | Yes | `KEY=value` |
| HTTP headers | Yes | `Content-Type: text/html` |
| logfmt | Yes | `level=info msg="hello"` |
| CSV/TSV | Yes | `name,age\nAlice,30` |
| Plain text | Fallback | Key-value extraction and substring search |
Auto-detection works in most cases. Use `-i` to override when the input is ambiguous.
## Install
### Cargo (Rust)
```bash
cargo install pick-cli
```
### Homebrew (macOS/Linux)
```bash
brew install aryanbhosale/pick/pick
```
### npm
```bash
npm install -g @aryanbhosale/pick
```
### Snap (Linux)
```bash
snap install pick-cli
```
### Chocolatey (Windows)
```powershell
choco install pick
```
### WinGet (Windows)
```powershell
winget install aryanbhosale.pick
```
### Docker
```bash
### GitHub Releases
Download pre-built binaries from [Releases](https://github.com/aryanbhosale/pick/releases) — macOS (ARM/x64), Linux (x64/ARM64), and Windows (x64).
### From source
Requires [Rust](https://rustup.rs/) 1.85+:
```bash
git clone https://github.com/aryanbhosale/pick.git
cd pick
cargo install --path .
```
## Contributing
Contributions are welcome! Here's how to get started:
1. Fork the repository
2. Create a feature branch: `git checkout -b my-feature`
3. Make your changes
4. Run the tests: `cargo test`
5. Commit and push: `git push origin my-feature`
6. Open a pull request
### Development
```bash
# Run all tests (866 tests)
cargo test
# Run a specific test
cargo test test_name
# Build release binary
cargo build --release
# The binary will be at target/release/pick
```
### Project Structure
```
src/
main.rs Entry point, stdin/file reading, streaming
lib.rs Orchestration and format routing
cli.rs CLI argument definitions
error.rs Error types
selector/ Selector engine (modular)
types.rs AST types (Expression, Pipeline, Selector, Filter, etc.)
parser.rs Hand-rolled recursive descent parser
extract.rs Path traversal and pipeline execution
filter.rs Filter evaluation (select, comparisons, regex)
manipulate.rs set() and del() operations
detector.rs Format auto-detection heuristics
output.rs Output formatting (plain, JSON, YAML, TOML)
streaming.rs JSONL streaming processor
formats/ Per-format parsers
json.rs, yaml.rs, toml_format.rs, env.rs,
headers.rs, logfmt.rs, csv_format.rs, text.rs
tests/
integration.rs CLI integration tests
```
## Issues
Found a bug or have a feature request? [Open an issue](https://github.com/aryanbhosale/pick/issues).
## License
[MIT](LICENSE)