Is there a script/program/utility already available for the following requirement in a optimised way?

someCommand |
   tee >(grep "pattern" > LinesWhichMatch) |
   grep -v "pattern" > LinesWhichDoesNotMatch

You could use awk for that.

command | awk '{ if (/pattern/) { print > "match" } else { print > "nomatch" } }'
  • 1
    I'm not completely familiar with awk but at what point does it evaluade the > ? If it's evaluated each time the conditional applies, you'd wind up with two one-line files... – Shadur Sep 22 '11 at 11:40
  • 1
    @Shadur > prints all output to the file, overwriting existing files. It isn't evaluated in such a way that it will result in any new lines overwriting old output from the same instance of awk. That is, if there are multiple matches, the file "match" will contain each match separated by OFS. The difference between > and >> exists in treatment of existing files. – Chris Down Sep 22 '11 at 11:43

Here is a sed example:
Note: sed's w command will overwrite an existing file each time the script is run, but only if that particular write command is triggered; hence the rm

rm -f file-{yes,not}  
sed -ne '/pattern/bY; w file-not' -e 'b; :Y; w file-yes' file
  • Nice. Without branching: sed -n '/PATTERN/p;//! w file-not' infile >file-yes – don_crissti Apr 4 '15 at 22:29

You can append files in awk:

awk '{if (/pattern/) print >>"matched"; else print >>"unmatched"; }

or shorter:

awk '{print >>(/pattern/?"matched":"unmatched")}'
  • His example shows that he wants to overwrite the files if they exist, not append. – Chris Down Sep 22 '11 at 0:22

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.