#!/usr/bin/rexx -- -- A Generalized Rexx Filter that can be used in a pipe -- -- Usage: rexx filter.rex builtin-or-external-function-name(arg1, arg2, ...) -- or: rexx filter.rex < inputfile -- or: rexx filter.rex (boolean expression) -- -- Note 1: -- -- rexx (to invoke filter.rex) may or may not be required to get -- the redirection and piping working, dependent on the operating -- system and the REXX implementation and/or installation setup. -- -- External functions can have a simple structure, for instance: -- -- rexx filter.rex "cut.rex(!line,10:5)" or filter.rex "cut(!line,10:5)" -- -- parse arg line,poslen -- parse var poslen pos ':' length . -- /* possibly more logic, but return value should be a (modified) -- line or a boolean if the function is called as an expression */ -- return delstr(line,pos,length) -- -- Argument(s)/Option(s) or even all of the filter have to be quoted generally. -- On Windows: It's best to use '"' for all of the filtere and "'" for arguments. -- On *n?x: It's best to use "'" for all of the filter and '"' for arguments. -- On *n?x: Redirection (< and > or >> ) doesn't seem to work all of the time. -- -- Pipe variables: -- -- The input line from the pipe is represented by '!line'. -- The running line count is represented by '!count' -- The total nr of lines is respresented by '!lines' -- Using '!lines' in the filter implies buffering the input stream before -- any output is passed on to the next pipe stage. -- -- Example 1: rexx filter.rex changestr(needle,!line,newneedle) -- -- Example 2: rexx filter.rex strip(!line,'L','>') -- -- Example 3: rexx filter.rex < somefile.txt - just echoes the input -- -- Example 4: rexx filter.rex (pos('>',!line)>0) - a boolean expression -- -- Example 5: rexx filter.rex "(!count>10)" - skips first 10 lines of input -- -- Example 6: rexx filter.rex "(!count>!lines-10)" - shows last 10 lines of input -- -- rexx filter.rex 0) -- a buffered stage can delay the input stream nop end !buffered = (pos('!lines',!filter)>0) if (!buffered) then do -- buffer input stream on standard queue do !lines=1 by 1 while (lines()>0) queue linein() end !lines = queued() !queued = !lines if (!queued>0) then do -- prefetch the 1st line queue parse pull !line end end else do !queued = lines() if (!queued>0) then do -- prefetch the 1st line from stdin !line = linein() end end do !count=1 by 1 while (!queued>0) if (!filter = '') then do -- no filter just echoes the input !out = !line end else do if (substr(!filter,1,1)='(') then do drop !out -- to verify !out is a var later on interpret '!test =' !filter -- apply the test if (!test) then do -- if test yields .true it goes out !out = !line end end else do -- apply the filter interpret '!out =' !filter end end if (var("!out")) then do -- only write if we have something call lineout ,!out end if (!buffered) then do -- if buffered, next line from queue !queued = queued() if (!queued>0) then do parse pull !line end end else do -- not buffered, next line from stdin !queued = lines() if (!queued>0) then do !line = linein() end end end exit