Split stdout and pipe each piece to command

2019-08-06 16:59发布

问题:

I have a javascript file that looks like this.

var val = "foo"
console.log(val)
//EVALMD-STDOUT-FILE-DELIMETER
if (!val) var val = "bar"
console.log(val)
//EVALMD-STDOUT-FILE-DELIMETER
console.log(val)

I can run it two ways.

node example.js 

Or I can pipe it in with cat.

cat example.js | node 

I'm trying to figure out how I can split a stdout like cat example.js by a delimiter in my case //EVALMD-STDOUT-FILE-DELIMETER, and pipe each with node as a separate process, so instead of logging foo, foo,foo I should get foo, bar, then an error.

The file above should get split and interpreted into 3 'chunks'

one:

var val = "foo"
console.log(val)

two:

if (!val) var val = "bar"
console.log(val)

three:

console.log(val)

回答1:

A partial solution that can be extended if you know the number of splits in advance would be something like:

cat example.js | tee >(sed -n '1,_//EVALMD-STDOUT-FILE-DELIMETER_p' | node) >(sed -n '_//EVALMD-STDOUT-FILE-DELIMETER_,$p' | node) >/dev/null

with the last >/dev/null to keep tee from printing it to stdout as well

You could use perl to do it if you don't know things in advance with a script like:

open(my $out, "| node");
while(<>) {
    if(/\/\/EVALMD-STDOUT-FILE-DELIMETER/) {
        close($out);
        open($out, "| node");
        next;
    }
    print $out $_;
}

So you could cat a file into that, which you could either have as a perl script or you could collapse into a string and run it like

cat example.js | perl -nle 'open(my $out, "| node");while(<>) {if(/\/\/EVALMD-STDOUT-FILE-DELIMETER/) {close($out);open($out, "| node");next;}print $out $_;}'

or of course you could trivially modify the perl to read the file itself and so not to need the cat