Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ckp95/fwf
Interactively create sed/awk/grep/jq/etc commands with immediate feedback
https://github.com/ckp95/fwf
Last synced: 3 months ago
JSON representation
Interactively create sed/awk/grep/jq/etc commands with immediate feedback
- Host: GitHub
- URL: https://github.com/ckp95/fwf
- Owner: ckp95
- License: gpl-3.0
- Created: 2022-02-12T22:32:17.000Z (almost 3 years ago)
- Default Branch: master
- Last Pushed: 2023-02-07T13:24:16.000Z (almost 2 years ago)
- Last Synced: 2024-06-30T14:49:39.817Z (5 months ago)
- Language: Shell
- Size: 332 KB
- Stars: 32
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# fwf - Filter With Feedback
Interactively create [text-filtering](https://en.wikipedia.org/wiki/Filter_(software)) commands (`sed`, `jq`, `awk`, `grep`, etc) with immediate feedback.
https://user-images.githubusercontent.com/43073868/153730961-0041d2c8-d074-4fe3-9c59-26409a92b214.mp4
https://user-images.githubusercontent.com/43073868/153730962-527ad148-c4ba-4550-a946-4f6c29c986ac.mp4
This is a tool born of frustration with UNIX command-line text-filtering tools, like `sed`, `awk`, `jq`, and so on. Whenever I needed to use one, I would end up in a frustrating loop of "type command -> press enter -> see error / incorrect output -> type out command again -> repeat". I wanted something with **immediate** feedback so I could iteratively construct the filter string. I also didn't want to deal with the maddening incidental complexity that is shell quote-escaping.
So, I hacked together a pair of zsh scripts that let me type in a filter command and see the results live-update with every keypress. On exit, it edits the current zsh buffer so that the new prompt contains the previous command (minus `fwf`), plus whatever you typed. So you can immediately run it, or continue building up a longer command with more pipes and filters.
It uses the `fzf` utility to render the preview, since I'm lazy and didn't want to code such a thing myself.
I am very happy with the result. `fwf` makes exploration through the solution-space fast and cheap, resulting in less trawling through StackOverflow. The burden on working memory is reduced by showing the before-text, the after-text, and the filter string all on one screen, and by handling shell-escaping automatically. I used to hate `sed`, `awk`, and `jq`, but combined with `fwf` they are fun to use. I hope you find it useful as well.
## Installation:
### Manual
Install the files `fwf`, `_fwf_main`, and `_fwf_columnate` somewhere on
your fpath (for example, if you have `fpath=(~/.zsh $fpath)`, place them
in `~/.zsh`), then include `autoload -U fwf` in your `.zshrc` or another
startup file.### Using [zinit](https://github.com/zdharma-continuum/zinit)
Add the following to your zsh configuration:
```
zinit ice as"command"
zinit snippet 'https://raw.githubusercontent.com/ckp95/fwf/6a8cec7a401fdb1928648ac4a68077438392243f/_fwf_main'
export FPATH="$FPATH:$(which _fwf_main)"zinit ice as"command"
zinit snippet 'https://raw.githubusercontent.com/ckp95/fwf/6a8cec7a401fdb1928648ac4a68077438392243f/fwf'zinit ice as"command"
zinit snippet 'https://raw.githubusercontent.com/ckp95/fwf/6a8cec7a401fdb1928648ac4a68077438392243f/_fwf_columnate'
```## Usage:
```zsh
echo 'some string' | fwf [COMMAND]
```This will launch a `fzf` preview with two panes. The left pane is the original piped text, while the right pane is the transformed text. The transformed text is created by running `[COMMAND] ''` on every keystroke. So if you run `echo 'quick brown fox' | fwf sed -E` and then type `s/quick/slow/g`, the right pane will show the result of `echo 'quick brown fox | sed -E 's/quick/slow/g'`. When you press return, your command line will be edited to say `echo 'quick brown fox' | sed -E 's/quick/slow/g'`.
You don't need to type the enclosing single-quotes yourself; this is done for you. If there are quotes in your typed string, they will be properly escaped in the result.
This should work with any text-processing tool that reads from standard input, takes a string argument, and writes to stdout.
e.g.
```zsh
cat my_file.txt | fwf sed -E
cat my_file.txt | fwf awk
cat my_file.json | fwf jq
```## Caveats
- It only works by piping stuff into it, i.e. `something | fwf awk`, not `fwf something awk`.
- It writes the entire piped input into a temporary file and then reads that file into memory, so you might want to cut down big inputs with `head` first.
- It doesn't preserve colors / syntax highlighting.
- It only works in zsh.
- It writes the amended command on a new line in the terminal, rather than editing the existing line. There is probably a way to make it do that by leveraging zsh's tab-completion functionality, but I couldn't figure it out. If you know how to do it, let me know.## Dependencies:
- `fzf`
- `zsh`## Isn't this just like [`up`](https://github.com/akavel/up), but more restricted?
Mostly. `fwf` shows both the before and after of the text transformation, which `up` doesn't do. But `up` does let you chain together an arbitrary pipeline, rather than just explore the results of a single command. `fwf` doesn't do that. I don't want that kind of capability because you're one wrong move away from using a dangerous command like `rm` in a long pipeline and suddenly all is lost.
I just wanted something to help me write a single text filter at a time. Also I don't think `up` edits the command buffer on exit, but I suppose you could write a shell alias to make it do that, so that part is a wash.
That said, you can use `fwf` on dangerous commands, but this should stick out like a sore thumb as dangerous. Maybe I should put in a blacklist of commands so `fwf` just fails instantly when you try to use it on them: `rm` and `dd` would be on it for sure.