| stdfilt - Run a command but filter its STDOUT and STDERR |
stdfilt - Run a command but filter its STDOUT and STDERR
stdfilt [OPTIONS] [--] COMMAND [ARGS]
Run COMMAND and match each of its output lines (both stdout and stderr separately) against the filter rules given by command arguments (-f) or in files (-F). All filter expressions are evaluated and the last matching rule wins. So it's a good idea to add wider matching patterns first, then the more specific ones later.
Empty and comments are ignored as well as leading whitespace.
Comment is everything after a hashmark (#) preceded by whitespace or the while line if it starts with a hashmark.
Each line is a filter rule, of which syntax is:
[match_tags] [pattern [offset]] [replacer] [set_tags]
Tag names, each of them in square-bracket (eg. [blue] [red]).
The rest of the rule will be evaluated only if the tags are on the current stream.
Tags can be added, removed by the set_tags element.
If a rule only consists of match_tags tags, it opens a section in the filter file (and in -f arguments too). In this section, all rules are interpreted as they had the given match_tags of the section written in them. For example this filter-set selects all ranges in the output (and stderr) stream bound by those regexp patterns inclusively, and blocks everying in them except "errors":
/begin checking procedure/ [checking] /checking finished/+1 [/checking] [checking] !// /error/i [/checking]
The 2 streams, stdout and stderr are tagged by default by "STDOUT" and "STDERR" respectively: So this filters out everying in the stdout except "errors":
[STDOUT] !// /error/i [/STDOUT]
Regexp pattern (perlre(1)) to match to the streams' (stdout and stderr) lines.
In the form of /PATTERN/MODIFIERS.
Optionally prefixed with an exclamation mark (!) which negates the result.
Pass every line by //.
Exclude every line by !//.
If there is a pattern in the rule, replacement or tagging will only take place if the pattern matched (or not matched if it was negated).
If there is no pattern, only match_tags controls if the rest will be applied or not.
You may escape slash (/) in the PATTERN normally as it's customary in Perl,
by backslash, but to keep the filter expression parsing simple,
an escaped backslash itself (double backslash) at the end of the regexp pattern,
ie. just before the closing slash,
won't be noticed.
So type it as \x5C instead.
Further limitation, that only slash / can be used, others, eg. m{...} not.
A pattern may be followed by a plus sign and a number (+N)
to denote that the given action (string replacement, or tagging)
should take effect after the given number of lines.
This way you can exclude the triggering line from the tagging.
A pattern with offset but without replacer or set_tags is meaningless.
A s/// string substitution Perl expression.
Optionally with modifiers.
This can be abused to execute any perl code (with the "e" modifier).
The syntax is the same as for match_tags. But is the square-bracketed tags are at the right side of the pattern, then the tags are applied to the stream.
Remove tags by a leading slash, like [/blue].
set_tags is useful with a pattern.
Example filter:
/BEGIN/ [keyblock] /END/ [/keyblock] [keyblock] s/^/\t/
This prepends a TAB char to each lines in the output stream which are between the lines containing "BEGIN" and "END".
HUP - re-read filter files given at command line
Prefix each output (and stderr) lines with the COMMAND process'es PID:
stdfilt -f 's/^/$CHILD_PID: /' some_command...
Prefix each line with literal STDOUT/STDERR string:
stdfilt -f '[STDOUT]' -f 's/^/STDOUT: /' -f '[/STDOUT]' -f '[STDERR]' -f 's/^/STDERR: /' -f '[/STDERR]' some_command...
grep(1), stdbuf(1), logwall(8), perlre(1)