Read into a stem and use the STEM.0th element
Edit Macro
Sort into reverse order and take the first.
Count the legs and divde by four
(I suggested:
cp "//'DATA.SET.NAME(MEMBER)'" /dev/fd/1 | tail -1
.. )
But usually to such questions, Frank chimes in saying
it's a natural for DFSORT. Is it?
-- gil
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to list...@bama.ua.edu with the message: GET IBM-MAIN INFO
Search the archives at http://bama.ua.edu/archives/ibm-main.html
Sounds reasonable to me. SORT has some of the best I/O routines around.
Outside of that, if this were to be done often, then I'd write my own
program. In HLASM, assuming a sequential file, I'd look at the DS1LSTAR
(and DS1TRBAL if the DS is extended format). I would then use BSAM and
POINT myself at record 1 of either the last track or next-to-last track
and read forward from there until EOF. This does not apply to any other
dataset type.
--
John McKown
Senior Systems Programmer
HealthMarkets
Keeping the Promise of Affordable Coverage
Administrative Services Group
Information Technology
The information contained in this e-mail message may be privileged
and/or confidential. It is for intended addressee(s) only. If you are
not the intended recipient, you are hereby notified that any disclosure,
reproduction, distribution or other use of this communication is
strictly prohibited and could, in certain circumstances, be a criminal
offense. If you have received this e-mail in error, please notify the
sender by reply and delete this message without copying or disclosing
it.
You can do this in many different ways with the sort. Assuming an
80-byte record the following control cards is one way you can accomplish
this:
INREC FIELDS=(1,80,SEQNUM,4,BI)
SORT FIELDS=(81,4,BI,D)
Paul Gilmartin wrote on 07/20/2007 07:13:38 AM:
> There's a thread active in TSO-REXX in which the OP wished
> to extract the last record from a data set. Of course, this
> spawns a school of increasingly byzantine suggestions:
>
> Read into a stem and use the STEM.0th element
>
> Edit Macro
>
> Sort into reverse order and take the first.
>
> Count the legs and divde by four
>
> (I suggested:
>
> cp "//'DATA.SET.NAME(MEMBER)'" /dev/fd/1 | tail -1
>
> ... )
>
> But usually to such questions, Frank chimes in saying
> it's a natural for DFSORT. Is it?
Here's a way to get the last record with DFSORT/ICETOOL in one copy pass.
I assumed the input file has RECFM=FB and LRECL=80, but the job
can be changed appropriately for other attributes. The trick is
to add the same value to every record and use the LAST parameter of
ICETOOL SELECT to get the last record. Normally, SELECT would do a SORT,
but we use SORT FIELDS=COPY to force it to do a COPY instead.
//S1 EXEC PGM=ICETOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//IN DD DSN=... input file (FB/80)
//OUT DD DSN=... output file (FB/80)
//TOOLIN DD *
SELECT FROM(IN) TO(OUT) ON(81,1,CH) LAST USING(CTL1)
/*
//CTL1CNTL DD *
INREC OVERLAY=(81:C'0')
SORT FIELDS=COPY
OUTFIL FNAMES=OUT,BUILD=(1,80)
/*
Of course, if you already happen to have the same value in all of the
records, this can be simplified even more. For example, if every record
had a blank in position 5, you could use this DFSORT/ICETOOL job:
//S2 EXEC PGM=ICETOOL
//TOOLMSG DD SYSOUT=*
//DFSMSG DD SYSOUT=*
//IN DD DSN=... input file
//OUT DD DSN=... output file
//TOOLIN DD *
SELECT FROM(IN) TO(OUT) ON(5,1,CH) LAST USING(CTL1)
/*
//CTL1CNTL DD *
SORT FIELDS=COPY
/*
BTW, here's a clever DFSORT/ICETOOL trick Graham Harris sent me that gets
the last n records of any file:
//LASTN EXEC PGM=ICETOOL
//DFSMSG DD SYSOUT=*
//TOOLMSG DD SYSOUT=*
//IN DD DSN=... input file
//OUT DD DSN=... output file
//TOOLIN DD *
COPY FROM(IN) USING(CTL1)
COPY FROM(IN) TO(OUT) USING(CTL2)
/*
//CTL1CNTL DD *
* Set n in SKIPREC=n to the number of records needed.
* For example, if you want the last 10 records,
* use SKIPREC=10.
OPTION SKIPREC=n <-- set n to the number of records needed
OUTFIL FNAMES=CTL2CNTL,REMOVECC,NODETAIL,BUILD=(80X),VTOF,
TRAILER1=(3:C'OPTION SKIPREC=',COUNT=(M11,LENGTH=12))
/*
//CTL2CNTL DD DISP=(,PASS),DSN=&&C2,SPACE=(TRK,1),UNIT=SYSDA
Frank Yaeger - DFSORT Development Team (IBM) - yae...@us.ibm.com
Specialties: PARSE, JFY, SQZ, ICETOOL, IFTHEN, OVERLAY, Symbols, Migration
=> DFSORT/MVS is on the Web at http://www.ibm.com/storage/dfsort/
>//CTL1CNTL DD *
> SORT FIELDS=COPY
>/*
Wouldn't this be a good use for a zero-length key, which could be
presumed to be present and identical in every record, e.g.:
//TOOLIN DD *
SELECT FROM(IN) TO(OUT) ON(1,0,CH) LAST USING(CTL1)
Will this work? Why not? I suspect I know the answer, but, still, why?
-- gil
Paul Gilmartin wrote on 07/20/2007 08:39:33 AM:
> >SELECT FROM(IN) TO(OUT) ON(5,1,CH) LAST USING(CTL1)
> >/*
> I'm guessing that the ON clause tells it to look in position 5,
> but what tells it that a blank is what it's supposed to look for?
DFSORT isn't looking for a blank - it's just looking for the same
value in position 5 of every record.
ON(5,1,CH) tells DFSORT to compare on position 5 of each record.
LAST tells DFSORT to take the last record for each compared value.
To get the last record in the file, we just need to have position 5
be the same for every record. Position 5 in every record can have
a blank or an asterisk or anything else.
> Wouldn't this be a good use for a zero-length key, which could be
> presumed to be present and identical in every record, e.g.:
>
> //TOOLIN DD *
> SELECT FROM(IN) TO(OUT) ON(1,0,CH) LAST USING(CTL1)
>
> Will this work? Why not? I suspect I know the answer, but, still, why?
No, it won't work. 0 is invalid for the length in an ON field so you'll
get a syntax error. Using a 0 length key would be one way to allow this
kind of thing, but there would be other ways as well.
Frank Yaeger - DFSORT Development Team (IBM) - yae...@us.ibm.com
Specialties: PARSE, JFY, SQZ, ICETOOL, IFTHEN, OVERLAY, Symbols, Migration
=> DFSORT/MVS is on the Web at http://www.ibm.com/storage/dfsort/
----------------------------------------------------------------------
That was my first thought when I saw the original post, but life
has a way of being difficult - what if it's VBS with a very,
very long last record?
Gerhard Postpischil
Bradford, VT
new e-mail address: gerhardp (at) charter (dot) net
I guess, in that case, you'd need to detect that and start "reading
backwards" to find the first segment. Not a fun thing to consider. Or
just not bother to support VBS with a message like: "VBS is for SMF
only. Get a life!"
--
John McKown
Senior Systems Programmer
HealthMarkets
Keeping the Promise of Affordable Coverage
Administrative Services Group
Information Technology
The information contained in this e-mail message may be privileged
and/or confidential. It is for intended addressee(s) only. If you are
not the intended recipient, you are hereby notified that any disclosure,
reproduction, distribution or other use of this communication is
strictly prohibited and could, in certain circumstances, be a criminal
offense. If you have received this e-mail in error, please notify the
sender by reply and delete this message without copying or disclosing
it.
----------------------------------------------------------------------
1) I had a life, but I squandered it working in the computer
industry (I started with a 704 PoPs, and it's gone downhill ever
since <g>).
2) IBM chose VBS as the default record format for unformatted
ForTran WRITEs. So while it would be nice to keep applications
away from it, it's not easy.
Gerhard Postpischil
Bradford, VT
new e-mail address: gerhardp (at) charter (dot) net
----------------------------------------------------------------------