help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] Is it possible to combine here-doc and pipeline?


From: Pierre Gaston
Subject: Re: [Help-bash] Is it possible to combine here-doc and pipeline?
Date: Fri, 28 Jul 2017 09:56:55 +0300

On Fri, Jul 28, 2017 at 2:38 AM, Andy Chu <address@hidden> wrote:

> On Thu, Jul 27, 2017 at 4:04 PM, Peng Yu <address@hidden> wrote:
>
> >
> > I think there is not a way to combine here-doc and pipeline based on
> > my test. Could anyone confirm if this is the case? Thanks.
> >
>
>
> Syntactically, a here doc can go anywhere a regular redirect can go.  Since
> regular redirects can be combined with pipelines, so can here docs.
>
> Eduardo pointed out this way:
>
> cat <<EOF | sed 's/a/b/g'
> > what a wonderful world
> > EOF
>
> You can also do it like this:
>
>
> cat <<EOF |
> what a wonderful world
> EOF
> sed 's/a/b/g'
>
> (Although for some reason this only works in batch mode rather than
> interactively)
>
> The way to think of it is that here doc delimiter is a placeholder for the
> literal string that comes later.  So the last two examples are analogous
> to:
>
> cat <<< 'here doc' | sed 's/a/b/g'
>
> and
>
> cat <<< 'here doc' |
> sed 's/a/b/g'
>
> respectively.
>
> You can also have multiple here docs on a line, like this:
>
> $ cat <<EOF1; cat <<EOF2
> > one
> > EOF1
> > two
> > EOF2
> one
> two
>
> Similarly,
>
> cat <<EOF1 | cat <<EOF2
>
> and
>
> cat <<EOF1 && cat <<EOF2
>
> are also valid.
>
> If you want to know all the gory details, read my blog post:
>
> http://www.oilshell.org/blog/2016/10/17.html
>
> Summary: here docs are parsed in a post-order traversal of the shell AST.
> I had no idea about this or even about multiple here docs on a line before
> I implemented a shell parser!
>
> This turns out to be trivial to implement, but IMO very hard for the user
> to read.  So I would stick with simple uses in your code.  One way to make
> it simpler is to wrap the here doc in a function:
>
> f1() {
>   cat <<EOF
> what a wonderful world
> EOF
> }
>
> f1 | sed 's/a/b/g/'   # same thing semantically, but semantically there's
> no here doc combined with a pipeline.
>
>
> Andy
>

Just for the completion, and maybe the most straightforward answer, you can
also use grouping without a function (just put the closing } on a new line)

{
cat << EOF
world
EOF
}  |  sed 's/^/hello, /'

or the variant:

{ cat |  sed 's/^/hello, /'; } << EOF
world
EOF


reply via email to

[Prev in Thread] Current Thread [Next in Thread]