# text-shark A Go CLI for fast text search, in-place replacement, line deletion, and file deletion. Powered by [`rg`](https://github.com/BurntSushi/ripgrep) for content operations and [`fd`](https://github.com/sharkdp/fd) for file-name finding. ## Prerequisites - [ripgrep](https://github.com/BurntSushi/ripgrep) (`rg`) - [fd](https://github.com/sharkdp/fd) (`fd`) - Go 1.21+ (to build from source) **Install on Ubuntu/Debian:** ```sh sudo apt install ripgrep fd-find ``` **Install on macOS:** ```sh brew install ripgrep fd ``` ## Installation ```sh git clone https://github.com/jasonross/text-shark cd text-shark go build -o text-shark . ``` Move the binary somewhere on your `$PATH`: ```sh mv text-shark /usr/local/bin/ ``` ## Commands ### `find` Search for a pattern in file contents. Output is streamed directly from `rg`, preserving colors and formatting. ```sh text-shark find [path] ``` ```sh text-shark find 'TODO' text-shark find 'TODO' ./src text-shark find -i 'error' # case-insensitive text-shark find -t go 'context' # Go files only text-shark find -g '*.json' 'port' # glob filter text-shark find -F 'foo.bar' # literal string (no regex) ``` | Flag | Description | |------|-------------| | `-i`, `--ignore-case` | Case-insensitive search | | `-F`, `--fixed-strings` | Treat pattern as a literal string | | `-t`, `--type` | File type filter (e.g. `go`, `py`, `js`) | | `-g`, `--glob` | Glob pattern for file paths | --- ### `replace` Replace all occurrences of a string (or regex) in matching files. Reports each modified file and the line numbers that changed. ```sh text-shark replace [path] ``` ```sh text-shark replace 'foo' 'bar' text-shark replace 'foo' 'bar' ./src text-shark replace 'foo' 'bar' --dry-run # preview changes without writing text-shark replace -r 'foo\d+' 'item' ./src # regex mode text-shark replace -t go 'oldPkg' 'newPkg' # Go files only ``` **Example output:** ``` ./internal/config.go: lines 12, 47 ./cmd/root.go: lines 3 2 file(s) modified. ``` | Flag | Description | |------|-------------| | `--dry-run` | Print what would change without writing files | | `-r`, `--regex` | Treat `` as a regular expression | | `-t`, `--type` | File type filter | | `-g`, `--glob` | Glob pattern for file paths | --- ### `delete-line` Delete all lines containing a pattern. Reports each modified file and the original line numbers that were removed. ```sh text-shark delete-line [path] ``` ```sh text-shark delete-line 'debug' text-shark delete-line 'debug' ./src text-shark delete-line 'debug' --dry-run text-shark delete-line -r '^#.*TODO' ./src # regex mode text-shark delete-line -t py 'print(' ./lib # Python files only ``` **Example output:** ``` ./internal/server.go: deleted lines 5, 23 ./cmd/run.go: deleted lines 1 2 file(s) modified, 3 line(s) deleted. ``` | Flag | Description | |------|-------------| | `--dry-run` | Print what would change without writing files | | `-r`, `--regex` | Treat pattern as a regular expression | | `-t`, `--type` | File type filter | | `-g`, `--glob` | Glob pattern for file paths | --- ### `find-delete-files` Find files by **name pattern** using `fd`, display the full candidate list, then prompt for a single group confirmation before deleting. ```sh text-shark find-delete-files [path] ``` ```sh text-shark find-delete-files '_backup' text-shark find-delete-files '_backup' ./archive text-shark find-delete-files '_backup' --yes # skip prompt (scripting) text-shark find-delete-files '\.log$' -t f ./logs # files only, regex name ``` **Example output:** ``` Found 3 file(s): ./archive/data_backup.csv ./archive/config_backup.json ./logs/old_backup.log Delete these 3 file(s)? [y/N] y 3 file(s) deleted. ``` | Flag | Description | |------|-------------| | `-y`, `--yes` | Skip confirmation prompt and delete all matches | | `-t`, `--type` | fd type filter: `f` (file), `d` (dir), `l` (symlink) — defaults to `f` | --- ## Notes - All `replace` and `delete-line` writes are **atomic**: changes are written to a temp file in the same directory, then renamed into place, so a failure mid-write cannot corrupt the original. - `path` defaults to `.` (current directory) on all subcommands. All operations are recursive. - `replace` and `delete-line` use `rg -l` internally to skip files that don't contain the pattern before doing any I/O. ## Running Tests ```sh go test ./... ```