Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a script outputting some value/numbers and I want to split those into two files. I am looking at something like:

./runme.sh | grep 'ook' >> ook.out | grep 'eek' >> eek.out

Where the second pipe should not, as is the case, take the output of the first grep but that of runme.sh. Is that possible?

share|improve this question
    
Tried something like the Print odd-numbered lines, print even-numbered lines answers adapted for your requirement? –  manatwork Dec 16 '11 at 12:16
    
@manatwork: It could but would be a hack. pee appears to do just what I want. –  Sardathrion Dec 16 '11 at 12:38
    
sed and awk can solve this in 1 process. With pee you will start 3 processes. Hack or not, sounds more efficient. –  manatwork Dec 16 '11 at 12:51
1  
@manatwork can you please give an example with sed and awk? I am interested to know the command build. –  Nikhil Mulley Dec 16 '11 at 12:57
add comment

5 Answers 5

up vote 5 down vote accepted

That's perfect use case for the utility pee.

./runme.sh | pee "grep ook >> ook.out" "grep eek >> eek.out"

In Debian & derivatives, pee is found in moreutils package.

share|improve this answer
    
that was good one minaev :-) –  Nikhil Mulley Dec 16 '11 at 12:34
    
I have to say I think @Nikhil's answer is more versatile as you might not be able to pee on all systems. –  cwd Jan 7 '12 at 15:12
add comment

You should do egrep for both patterns then.

`/.runme.sh | egrep "ook|eek"

but it seems you need to redirect the each pattern evaluation output to its own file, which grep does not seem to support. Anyone, please correct me if it is possible.

Edit: minaev gave a working example with pee from moreutils, but if pee is missing on your platform, we can still use tee like this. Just play with process substitution.

./runme.sh |tee >(grep ook > ook.txt) >(grep eek > eek.txt)

Example:

[centos@centos scripts]$ ./runme.sh
eekfarapplebin
keeekmajowrwt
keekookjsfskooeek
ook
[centos@centos scripts]$ ./runme.sh | tee >(grep eek >eek.txt) >(grep ook >ook.txt)
eekfarapplebin
keeekmajowrwt
keekookjsfskooeek
ook
[centos@centos scripts]$ cat eek.txt 
eekfarapplebin
keeekmajowrwt
keekookjsfskooeek
[centos@centos scripts]$ cat ook.txt 
keekookjsfskooeek
ook
[centos@centos scripts]$ 
share|improve this answer
1  
+1 That is hard core. Thanks. –  Sardathrion Dec 16 '11 at 12:53
    
you are welcome :-) –  Nikhil Mulley Dec 16 '11 at 12:55
add comment

The simple awk alternative:

./runme.sh | awk '/ook/{print>>"ook.out"}/eek/{print>>"eek.out"}'

With little addition the awk code can be made easily extensible – just put in array r as many regular expression-output file pairs are needed:

./runme.sh | awk 'BEGIN{r["ook"]="ook.out";r["eek"]="eek.out"}{for(i in r)if($0~i)print>>r[i]}'

The sed w command is equivalent of >, sadly there is no way to append to file:

./runme.sh | sed -n $'/ook/wook.out\n/eek/week.out'
share|improve this answer
    
+1 superb answer indeed. –  Sardathrion Dec 16 '11 at 13:31
    
+1 this one goes into my commandsmagic bag –  Nikhil Mulley Dec 16 '11 at 13:41
add comment

I'm guessing runme is either a long running command, or requires atomicity (runs once).

I would suggest creating a unique temp filename with mktemp

TMPFILE=$(mktemp)
./runme.sh > $TMPFILE
grep 'ook' $TMPFILE >> ook.out
grep 'eek' $TMPFILE >> eek.out
\rm -f $TMPFILE
share|improve this answer
    
See Nikhil's answer for a clever use of tee... –  Sardathrion Dec 16 '11 at 12:53
1  
I saw that, so I stand corrected on the use of tee My old learn linux mantra - learn something new everyday, try it, practice it, remember it. –  bdowning Dec 16 '11 at 16:05
    
@dbowning: Tru dat. –  Sardathrion Dec 16 '11 at 16:07
add comment

The command tee can keep a copy of the piped stream in a temp file. Then we can grep the original stdout and also the temp file separately:

./runme.sh |tee temp |grep ook >>ook.out;grep eek temp >>eek.out
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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