I'm looking for a program to use an external program to filter the lines of a stream – pretty much a version of grep
that, for each line, prints or suppresses it based on whether the specified program exits with a zero exit code (like find
's -exec
option).
I know that I can do this in shell by using a loop and a subshell:
some-program |(while read line; do
if predicate "$line"; then
echo "$line"
fi
done)
What I'm wondering is if there's a program floating around that will let me make this simpler:
some-program |filter predicate
# want negation as well
some-program |filter ! predicate
One would think that an enhanced Sed might support this, asking "does it pass on the pattern space?", but GNU Sed does not seem to have such a facility.
Is there such a program somewhere that I haven't found, or do I just need to do it in shell (or perl)?
Best Answer
The shell is a perfectly suitable tool for this job. Just take care not to mangle spaces and backslashes.
You could also use awk. Be sure to quote each line since it'll be passed to a shell (the snippet below puts single quotes around the line, and replaces single quotes in the line by
'\''
;\047
is'
). Because each command invocation goes through a shell, I expect this to be slower than the pure shell method, even if awk is likely to be faster at parsing lines. But I haven't made any benchmarks.