Operating System - OpenVMS
1748145 Members
3407 Online
108758 Solutions
New Discussion юеВ

Re: Can you do a F$EXTRACT on a PIPE output

 
Niall76
Frequent Advisor

Can you do a F$EXTRACT on a PIPE output

Hi,

I'm trying to extract certain sections of lines in a report. First I find the lines I want and then I attempt to extract the section of that line I want. I would like to be able to do this without creating any temporary files, but just using the sys$input. Here is my attempt:

pipe typ sample.rep | search/match=and SYS$INPUT 8148, 5.00 | READ/END_OF_FILE=exit SYS$inPUT record F$EXTRACT(12,10,RECORD)

It works up to the second pipe, I'm just not able to 'extract' the section of the line I want out of the terminal output. Can anyone help me out please?

Thanks,
Niall
12 REPLIES 12
Joseph Huber_1
Honored Contributor

Re: Can you do a F$EXTRACT on a PIPE output

Correct the second part to read:

(READ SYS$PIPE record ; record=F$EXTRACT(12,10,RECORD) ; define/job record &record)

A READ in a pipe can have no error/end label (where do You think the label "exit" is ?)
If You want to have read error handling, and/or read of more than one line, then pipe into a DCL command-file, which does a loop on READ SYS$PIPE: Your search most probably DOES output more than one line to the pipe !
The above SEARCH+READ only gets the first line, not what You want. use SEARCH/WINDOW=1 .
http://www.mpp.mpg.de/~huber
Hein van den Heuvel
Honored Contributor

Re: Can you do a F$EXTRACT on a PIPE output


Niall, what are you going to do with the result? Stick it in a logical?
And then what? What problem are you really trying to solve, and is convoluted DCL really the best way to go about that?

Here is some DCL that works for me.
I dropped the first pipe segment as search is perfectly able to read a file itself. It needs no help from type does it?

$ pipe typ tmp.tmp | search/match=and SYS$INPUT 8148, 5.00 | (read sys$pipe x ; x=f$extr(12,10,x) ; def/job x &x)
$ show log x

Using PERL this looks like:

$ perl -lne "print substr($_,12,10) if /8148/ && /5.00/" tmp.tmp

Or AWK if you prefer...

$ gawk "/8148/ && /5.00/ { print substr($_,13,10) }" tmp.tmp

If more string processing needs to take place, or more complex matching algorithms are needed (general, not specific values and/or more rigorous placement/anchors for the match strings), then a perl or awk solution with REGULAR EXPRESSIONS quickly becomes more advantageous.

For example:

$ perl -ne "print $1 if /^\s*8148.*?5.00(.{10})/" tmp.tmp


That REGEXPR says look for a like starting with (^) optional whitespace (\s*) followed by 8184 followed by any number of anything (.*?) up to 5.00, then save (()) 10 times anything (.{10}) into register $1

Often one of two of those number are variables which need to be picked up, and the string of 10 is really just a single word.
The line might then become

$perl -ne "print qq($2 $1) if /^\s*8148\s+([0-9.]+)\s*(\w+)/" tmp.tmp

^ = Begin of line
\s = whitespace
\s+ = 1 whitespace or more
\s* = any number of whitespace
[0-9.] any character in the range 0 - 9 or a period
[0-9.]+ = series of one or more of those
\w = a word character
\w+ = a word
qq() = double quoted string doing substitutions (avoid quote fights with DCL)

hth,
Hein





Joseph Huber_1
Honored Contributor

Re: Can you do a F$EXTRACT on a PIPE output

Example:

$ pipe typ sample.rep | search/match=and SYS$INPUT 8148, 5.00 | @logical_from_pipe RECORD

$ record=f$trnlnm("RECORD","LNM$GROUP")
$ this = F$EXTRACT(12,10,RECORD)

Where logical_from_pipe.com is
http://www.mpp.mpg.de/~huber/util/com/logical_from_pipe.com

A version reading more than one line from pipe into logicals was posted by R.Boyd here (or at www.openvms.org ?), You can find my version on the above web location as logicals_from_pipe.com .
http://www.mpp.mpg.de/~huber
Hein van den Heuvel
Honored Contributor

Re: Can you do a F$EXTRACT on a PIPE output

Actually... I did not drop the 'type' command in the example I happende to cut & paste.

Correction:

$ pipe search/match=and tmp.tmp 148, 5.00 | (read sys$pipe x ; x=f$extr(12,10,x) ; def/job x &x)


Using perl and defining a logical(*)

$perl -ne "$ENV{x} = substr($_,12,10) if /8148/ && /5.00/" tmp.tmp
$ show log x


(*) For the latter, see also
http://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1408424


Hein


Niall76
Frequent Advisor

Re: Can you do a F$EXTRACT on a PIPE output

thanks guys for your quick responses. You have probably guessed that I don't really know what I'm doing and the fact that I should have mentioned I wanted it to loop. When I do the search this way I get:

pipe search/match=and sample.txt 8148, 5.00
AAAA 0 0 0 5.00 8148 AA1234 1426 2216 ...
AAAA 0 0 0 5.00 8148 AA12345 3287 2216 ...
AAAA 0 0 0 5.00 8148 AA756 703 2216 ...

With the new and improved pipe:
$ pipe search/match=and sample.txt 8148, 5.00 | (read sys$pipe info ; x=f$extr(37,4,info) ; y=f$extr(41,10,info) ; write sys$output x, y)
8148 AA1234

But what I want is:
8148 AA1234
8148 AA12345
8148 AA756

I'm sorry, but from your examples and links I can't figure out how to do it.

Thanks,
Niall
Graham Burley
Frequent Advisor

Re: Can you do a F$EXTRACT on a PIPE output

Sounds like you really need a port of the unix cut utility to complete your pipe-fest.

It's possible that SORT can do it for you, depending on what the input file is really like (space aligned, etc). Making some assumptions about what you posted, an example:

$ type a.a
0000000001111111111222222222233333333334444444444555555555566666666667
1234567890123456789012345678901234567890123456789012345678901234567890
AAAA 0 0 0 5.00 8148 AA1234 1426 2216 ...
AAAA 0 0 0 5.00 8148 AA12345 3287 2216 ...
AAAA 0 0 0 5.00 8148 AA756 703 2216 ...

$ type a.srt
/field=(name=f1,pos:33,siz:4)
/field=(name=f2,pos:38,siz:4)
/field=(name=f3,pos:43,siz:9)
/condition=(name=c1,test=((f1 eq "5.00") and (f2 eq "8148")))
/include=(condition=c1)
/data=f2
/data=f3

$ sort a.a /spec=a.srt sys$output
8148 AA756
8148 AA1234
8148 AA12345
RBrown_1
Trusted Contributor

Re: Can you do a F$EXTRACT on a PIPE output

If you want to have a loop, then you need to put the DCL that does the READ ... WRITE in a command file and code a loop. Then you could PIPE SEARCH/MATCH=AND SAMPLE.REP 8148,5.00 | @FILTER for example.

hth
RBrown_1
Trusted Contributor

Re: Can you do a F$EXTRACT on a PIPE output


I see that Graham and I got the same time stamp! :-)
Graham Burley
Frequent Advisor

Re: Can you do a F$EXTRACT on a PIPE output

And in posting that example all spacing was lost, hopefully the point wasn't.