ooRexx logo
   1: #!/usr/bin/rexx
   2: --
   3: -- A Generalized Rexx Filter that can be used in a pipe
   4: --
   5: -- Usage: rexx filter.rex builtin-or-external-function-name(arg1, arg2, ...)
   6: --    or: rexx filter.rex < inputfile
   7: --    or: rexx filter.rex (boolean expression) 
   8: --
   9: -- Note 1:
  10: --
  11: --    rexx (to invoke filter.rex) may or may not be required to get 
  12: --    the redirection and piping working, dependent on the operating
  13: --    system and the REXX implementation and/or installation setup.  
  14: --  
  15: -- External functions can have a simple structure, for instance: 
  16: --          
  17: --    rexx filter.rex "cut.rex(!line,10:5)" or filter.rex "cut(!line,10:5)"
  18: --
  19: --    parse arg line,poslen
  20: --    parse var poslen pos ':' length .
  21: --    /* possibly more logic, but return value should be a (modified)
  22: --       line or a boolean if the function is called as an expression */
  23: --    return delstr(line,pos,length)  
  24: --  
  25: -- Argument(s)/Option(s) or even all of the filter have to be quoted generally.
  26: -- On Windows: It's best to use '"' for all of the filtere and "'" for arguments.
  27: -- On *n?x: It's best to use "'" for all of the filter and '"' for arguments.
  28: -- On *n?x: Redirection (< and > or >> ) doesn't seem to work all of the time.
  29: --
  30: -- Pipe variables:
  31: --
  32: -- The input line from the pipe is represented by '!line'. 
  33: -- The running line count is represented by '!count' 
  34: -- The total nr of lines is respresented by '!lines'
  35: -- Using '!lines' in the filter implies buffering the input stream before 
  36: -- any output is passed on to the next pipe stage.
  37: --
  38: -- Example 1: rexx filter.rex changestr(needle,!line,newneedle)
  39: --
  40: -- Example 2: rexx filter.rex strip(!line,'L','>')
  41: --
  42: -- Example 3: rexx filter.rex < somefile.txt  - just echoes the input
  43: --
  44: -- Example 4: rexx filter.rex (pos('>',!line)>0) - a boolean expression 
  45: --
  46: -- Example 5: rexx filter.rex "(!count>10)" - skips first 10 lines of input
  47: --
  48: -- Example 6: rexx filter.rex "(!count>!lines-10)" - shows last 10 lines of input   
  49: --
  50: --    rexx filter.rex 0)	-- a buffered stage can delay the input stream 
  72:   nop
  73: end 
  74: !buffered = (pos('!lines',!filter)>0)
  75: if (!buffered) then do	-- buffer input stream on standard queue
  76:   do !lines=1 by 1 while (lines()>0)
  77:     queue linein()
  78:   end
  79:   !lines = queued()
  80:   !queued = !lines
  81:   if (!queued>0) then do	-- prefetch the 1st line queue
  82:     parse pull !line
  83:   end	
  84: end
  85: else do
  86:   !queued = lines()
  87:   if (!queued>0) then do	-- prefetch the 1st line from stdin
  88:     !line = linein()
  89:   end 
  90: end
  91: do !count=1 by 1 while (!queued>0)
  92:   if (!filter = '') then do	-- no filter just echoes the input
  93:     !out = !line
  94:   end
  95:   else do 
  96:     if (substr(!filter,1,1)='(') then do
  97:       drop !out		-- to verify !out is a var later on	  				
  98:       interpret '!test =' !filter	-- apply the test
  99:       if (!test) then do 	-- if test yields .true it goes out
 100:         !out = !line
 101:       end
 102:     end
 103:     else do		-- apply the filter
 104:       interpret '!out =' !filter  
 105:     end
 106:   end
 107:    if (var("!out")) then do	-- only write if we have something 
 108:      call lineout ,!out 		
 109:   end
 110:   if (!buffered) then do	-- if buffered, next line from queue
 111: 	!queued = queued()
 112: 	if (!queued>0) then do
 113: 	  parse pull !line
 114: 	end
 115:   end
 116:   else do	-- not buffered, next line from stdin
 117:     !queued = lines()
 118: 	if (!queued>0) then do
 119: 	  !line = linein()
 120: 	end
 121:   end
 122: end
 123: exit
If you feel inclined to make corrections, suggestions etc., please mail me any.
All content © Ruurd Idenburg, 2007–, 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 by Ruurd Idenburg.