0

In kakoune (vim-like editor) I can press pipe, type a command, press enter, and it will run the command using the current selection as input, and replace that selection with the output of the command ran. For example, |jq<ret>, where <ret> is the Enter key, will format a json selection.

Sometimes though, I'd rather have the selection used as part of the command, instead of as the input. For example if I want to use cat to replace a file name with its content. Within Kakoune there's a handy shortcut to paste the current selection in the command prompt, but it doesn't work with multi-selection (running the same command multiple times with different i/o).

The solution I settled for is to expand the stdin using $(cat). For the previous example, I would press |cat $(cat)<ret>.

This use of $(cat) seems to rely on the specific (and degenerate?) way bash handles expansions and sub-process. For example, it doesn't work on zsh or fish where the expansion happens immediately and the input of cat is the output of the terminal, or I guess of whatever launched the command. Instead, in bash, the input of cat is the output of the command before the pipe.

I use this pattern outside of kakoune as well, for example:

pgrep code | ps -p $(cat) -O [options]

to use pgrep to search processes and use ps to format the informations I want to display (better than with pgrep -a), but kakoune pipe command is the one use case where I cannot use the more robust and maybe more idiomatic:

ps -p $(pgrep code) -O [option]

Kakoune defaults to sh which most often means bash or dash, so I'm fine, but since I primarily use fish as my interactive shell, I am still very curious about achieving something similar in fish. Namely:

How to expand stdin from a previously piped command, or how to generate and execute a command depending on stdin ?

I'm also curious about cleaner ways in bash.

One thing I love aobut interactive shell languages (as opposed to most programming language, or even to Nu) is the flexibility in the flow of information. For example, because I used to do them separately and in that order, pgrep code | ps -p $(cat) makes some sense to me, more than starting with ps, and I love having the choice. As for kak, short of writing down scripts or writing to temporary files, the pipe command does impose a constraint, which turns out rather strong despite being very reasonable.

1 Answer 1

0

It seems xargs is the answer to: "how to generate and execute a command depending on stdin ?"

For example xargs cat to prepend stdin with cat and execute it as a command, and pgrep code | xargs -I% ps -p % -O cmd using the -I option to do more complex things than preppending.

I won't mark the question solved just yet as I'm still curious of details and alternatives.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .