I want to make function that parses from text pasted in a terminal.

$ cat <<eof | grep --color sometext
> foo
> sometext
> sometext1
> a sometext
> asdf
> eof
a sometext

While the above works I can make neither an alias nor a function of it.

alias gsi='cat <<eof | grep --color "$1"'
gsi { cat <<eof | grep --color "$1" ; }

I thought redirections weren't executed during function definition.

alias 'gsi=<<eof grep --color'

Would work as alias is just like preprocessor text replacement, where the replacement is interpreted as shell code again.

Yours was not working as you had that "$1". With gsi file.txt replaced with cat <<eof | grep --color "$1" file.txt, then the shell carries on interpreting that command line and $1 at that point is the shell's first positional parameter which is probably empty unless you did a set something beforehand. So you'd want to remove that "$1" here. You can remove the UUOC as well.

gsi() { cat <<eof | grep --color "$1" ; }

is wrong from a syntax point of view as the eof line is missing after that cat <<eof.

  • Thanks, for emending the alias. I still don't understand why here-document is executed during function definition. – 1.61803 Aug 15 '18 at 16:14
  • @1.61803 it's not that the heredoc is executed, it's that the function body has to be syntactically complete so that bash can understand how much of what you have given is the function, unlike aliases which are essentially simple text replacements. – muru Aug 16 '18 at 0:31

Your function would not be using a here-document:

gsi () {
   grep --color "$@"

This would enable you to pass a pattern as well as any other options to grep on the common line and grep would read from standard input.

The end of the input would be signalled by pressing Ctrl+D.

The above would possibly intermingle the pasted contents and the result from grep. To accumulate the pasted content first and then run grep, you could use something like

gsi () {
    trap 'rm -f "$buffer"' RETURN
    local buffer="$(mktemp)"
    cat >"$buffer" && grep --color "$@" "$buffer"

Here, the pasted output is put into a temporary file before the grep is run. The temporary file is removed when the function exits. This is approximately what bash would do behind the scenes when you paste into a here-document.

  • 2
    This works, but is a bit awkward in that if the input is pasted to the terminal, it will get intermixed with output from grep. The here-doc works as a work-around for that, though I suppose one could wrap the grep within stty -echo and stty echo to hide the pasted text... – ilkkachu Aug 15 '18 at 14:38
  • @ilkkachu True, the here-document in the question would act like a temporary buffer. I'll try your suggestion and make an update when I'm in front of a computer later. – Kusalananda Aug 15 '18 at 15:03
  • @Kusalananda, ideally, I would have both pasted and greped text on screen. – 1.61803 Aug 15 '18 at 16:04

You mentioned you're pasting to terminal. Abandon here-doc altogether, and use a proper clipboard utility, such as xclip (or pbpaste on Mac OS X). With xclip that'd be done as

xclip -o -sel clip | grep --color 'sometext'

See also 'xclip' vs. 'xsel' on the difference between the two utilities.

  • Thanks for the suggestion, but in this case I rather not use additional software, which by the way isn't that widespread. – 1.61803 Aug 15 '18 at 16:13
  • @1.61803 Understandable. Hopefully, this helps to others. xclip is actually a fairly common software, at least across Linux repositories. – Sergiy Kolodyazhnyy Aug 15 '18 at 16:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.