Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Last Record

28 views
Skip to first unread message

"Paul GilmartinIBM-...@bama.ua.edu

unread,
Jul 20, 2007, 10:13:59 AM7/20/07
to
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?

-- 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

McKown, John

unread,
Jul 20, 2007, 10:37:08 AM7/20/07
to
> -----Original Message-----
> From: IBM Mainframe Discussion List
> [mailto:IBM-...@BAMA.UA.EDU] On Behalf Of Paul
> Gilmarti...@BAMA.UA.EDU
> Sent: Friday, July 20, 2007 9:14 AM
> To: IBM-...@BAMA.UA.EDU
> Subject: Last Record
>
>
> 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?
>
> -- gil

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.

Reda, John

unread,
Jul 20, 2007, 10:38:25 AM7/20/07
to
Gil,

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)

Frank Yaeger

unread,
Jul 20, 2007, 10:53:20 AM7/20/07
to

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/

Paul Gilmartin

unread,
Jul 20, 2007, 11:39:46 AM7/20/07
to
On Fri, 20 Jul 2007 07:48:03 -0700, Frank Yaeger wrote:
>
>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)
>/*
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?

>//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

Frank Yaeger

unread,
Jul 20, 2007, 1:15:52 PM7/20/07
to

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/

----------------------------------------------------------------------

Gerhard Postpischil

unread,
Jul 20, 2007, 4:15:26 PM7/20/07
to
McKown, John wrote:
> 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.

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

McKown, John

unread,
Jul 20, 2007, 4:27:00 PM7/20/07
to
> -----Original Message-----
> From: IBM Mainframe Discussion List
> [mailto:IBM-...@BAMA.UA.EDU] On Behalf Of Gerhard Postpischil
> Sent: Friday, July 20, 2007 3:15 PM
> To: IBM-...@BAMA.UA.EDU
> Subject: Re: Last Record
>
>
> McKown, John wrote:
> > 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.
>
> 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

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.

----------------------------------------------------------------------

Gerhard Postpischil

unread,
Jul 21, 2007, 1:39:41 AM7/21/07
to
McKown, John wrote:
> 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!"

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

----------------------------------------------------------------------

0 new messages