ooRexx logo filter.orx
#!/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 <filter.rex | ,
--    rexx filter.rex (pos('-',!line)=1) | ,
--    rexx filter.rex strip(!line,'L','-')
--
-- will first read and echo filter.rex,
-- then output only input lines that start with '-',
-- then strip leading comment identifier '--'.
--
-- No copyright, no license, no guarantees, use at your own risk.
--
-- And you just read the result of the pipe above.
--
parse source . . me  
parse arg !filter
do (!filter='?' | !filter='-?' | !filter='/?' | !filter='h' | !filter='-h' | !filter='/h' | !filter='--help')
  pipe = 'rexx "'me'"<"'me'" | rexx "'me'" (pos(''-'',!line)=1) | rexx "'me'" strip(!line,''L'',''-'')'
  pipe
  exit
end
!filter = strip(strip(strip(!filter,'B',' '),'B',"'"),'B','"')  -- strip spaces and quotes

do until (lines()>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
 
If you feel inclined to make corrections, suggestions etc., please mail me any.
All content © Ruurd Idenburg, 2007–2023, except where marked otherwise. All rights reserved. This page is primarily for non-commercial use only. The Idenburg website records no personal information and sets no ‘cookies’. This site is hosted on a VPS(Virtual Private System) rented from Transip.nl, a Dutch company, falling under Dutch (privacy) laws (I think).

This page updated on Fri, 07 May 2021 12:15:43 +0200 by Ruurd Idenburg.