|
View previous topic :: View next topic
|
| Author |
Message |
rajiv rengasamy
New User
Joined: 24 Sep 2008 Posts: 26 Location: Chennai
|
|
|
|
I have a file with each record of length 4 characters.
• All the records are left justified
• The record can be a string or a whole number or a decimal number
• There is no sign, the numbers are always positive
This file needs to sorted such that
The records with value string are at the top
followed by numerical values sorted in ascending order.
The below is the sample input
8999
bbbb
aaaa
cccc
299
abcc
abcd
0.1
0.7
9999
0.9
cefd
1
1.9
1.7
baed
---------
Desired output
aaaa
abcc
abcd
baed
bbbb
cccc
Cefd
0.1
0.7
0.9
1
1.7
1.9
299
8999
9999
Can you please guide/assist how this can be archived using sort utility.
Thank you
Rajiv R |
|
| Back to top |
|
 |
Rohit Umarjikar
Global Moderator

Joined: 21 Sep 2010 Posts: 3109 Location: NYC,USA
|
|
|
|
Can you explain why this did not work unless not tried?
| Code: |
//SYSIN DD *
SORT FIELDS=(1,4,CH,A)
//* |
|
|
| Back to top |
|
 |
Marso
REXX Moderator

Joined: 13 Mar 2006 Posts: 1356 Location: Israel
|
|
|
|
The sample data provided does not show the problem:
The below is the sample input
8999
bbbb
299
abcc
92 <===
0.1
5.7 <===
9999
cefd
1
1.9
output with (1,4,CH,A)
abcc
bbbb
Cefd
0.1
1
1.9
299
5.7 <===
8999
92 <===
9999
Desired output
abcc
abcd
bbbb
Cefd
0.1
1
1.9
5.7<===
92 <===
299
8999
9999 |
|
| Back to top |
|
 |
sergeyken
Senior Member

Joined: 29 Apr 2008 Posts: 2263 Location: USA
|
|
|
|
| Marso wrote: |
The sample data provided does not show the problem:
The below is the sample input
8999
bbbb
299
abcc
92 <===
0.1
5.7 <===
9999
cefd
1
1.9
output with (1,4,CH,A)
abcc
bbbb
Cefd
0.1
1
1.9
299
5.7 <===
8999
92 <===
9999
Desired output
abcc
abcd
bbbb
Cefd
0.1
1
1.9
5.7<===
92 <===
299
8999
9999 |
A sophisticated PARSE is needed.
There is no option in SORT to automatically recognize free-text decimal fractioned values, or left-aligned numeric values in the manner TS wants it. Formats like UFF etc. do not recognize decimal points, and ignore them. Formats like CH do consider numeric values as simple characters. Formats like ZD do not accept anything except digits '0'-'9'.
Some time ago I've posted a related example: how to parse unaligned decimal fractioned values using SORT tools.
But I suggest the TS to try something by himself using given hints, before giving him a ready-to-use solution. |
|
| Back to top |
|
 |
sergeyken
Senior Member

Joined: 29 Apr 2008 Posts: 2263 Location: USA
|
|
|
|
Looks like the most part of topic starters here are not interested neither in learning, nor in trying something by themselves, isn't it?
They are waiting for a ready-to-use solution OF THEIR JOB to be presented to them FREE OF CHARGE?
| Code: |
//*==================================================================
//* PROCESS FREE TEXT
//*==================================================================
//FREETEXT EXEC PGM=SYNCSORT
//*
//SYSOUT DD SYSOUT=*
//*
//SORTIN DD *
8999
bbbb
299
abcc
92 <===
0.1
5.7 <===
9999
cefd
1
1.9
//*
//SORTOUT DD SYSOUT=*
//*
//SYSIN DD *
* Add control fields based on three categories of input records
* CASE 1: no digits; consider simple string
INREC IFTHEN=(WHEN=(1,4,SS,NE,L(C'0', |
C'1', | none
C'2', |
C'3', | of any digit
C'4', |
C'5', | present?
C'6', |
C'7', |
C'8', |
C'9')), |
BUILD=(1,80, original record
4X, blank whole digit part
4X, blank fractional part
1,4)), non-digit, character value
* CASE 2: some digits, and decimal point: consider non-whole number
IFTHEN=(WHEN=(1,4,SS,EQ,C'.'), decimal point present?
PARSE=(%1=(ENDBEFR=C'.',FIXLEN=4), whole part
%2=(ENDBEFR=BLANKS,FIXLEN=4)), fraction part
BUILD=(1,80, original record
%1,JFY=(SHIFT=RIGHT), right-aligned whole part
%2,JFY=(SHIFT=LEFT), left-aligned fraction part
4X)), blank character value
* CASE 3: some digits, no decimal point: consider whole number
IFTHEN=(WHEN=NONE, otherwise: whole number
BUILD=(1,80, original record
1,4,JFY=(SHIFT=RIGHT), right-alighned whole part
4X, blank fraction part
4X)) blank character value
*
* re-order on created control fields
SORT FIELDS=(81,4,CH,A, whole number, if present
85,4,CH,A, fractional part, if present
89,4,CH,A) character part, if non-numeric
*
OUTREC BUILD=(1,80) restore original record
*
END
//* |
| Code: |
********************************* TOP OF DATA *********
abcc
bbbb
cefd
0.1
1
1.9
5.7 <===
92 <===
299
8999
9999
******************************** BOTTOM OF DATA ******* |
|
|
| Back to top |
|
 |
sergeyken
Senior Member

Joined: 29 Apr 2008 Posts: 2263 Location: USA
|
|
|
|
Clarification to the previous example.
This is how the intermediate records look like after SORT by control field, but before the original record is restored.
| Code: |
----+----1----+----2----+----3 . . . . 8----+----9----+
abcc abcc
bbbb bbbb
cefd cefd
0.1 01
1 1
1.9 19
5.7 <=== 57
92 <=== 92
299 299
8999 8999
9999 9999
|
|
|
| Back to top |
|
 |
sergeyken
Senior Member

Joined: 29 Apr 2008 Posts: 2263 Location: USA
|
|
|
|
It is not recommended to code the statements (in any language) in this "compacted" style.
If you do so to save 5 minutes today, then hard time in the future is guaranteed.
| Code: |
SORT FIELDS=(81,12,CH,A)
OUTREC BUILD=(1,80)
INREC IFTHEN=(WHEN=(1,4,SS,NE,L(C'0',C'1',C'2',C'3',C'4',C'5',
C'6',C'7',C'8',C'9')),BUILD=(1,80,4X,4X,1,4)),
IFTHEN=(WHEN=(1,4,SS,EQ,C'.'),PARSE=(%1=(ENDBEFR=C'.',FIXLEN=4),
%2=(ENDBEFR=BLANKS,FIXLEN=4)),BUILD=(1,80,%1,JFY=(SHIFT=RIGHT),
%2,JFY=(SHIFT=LEFT),4X)),IFTHEN=(WHEN=NONE,BUILD=(1,80,
1,4,JFY=(SHIFT=RIGHT),4X,4X))
|
|
|
| Back to top |
|
 |
Rohit Umarjikar
Global Moderator

Joined: 21 Sep 2010 Posts: 3109 Location: NYC,USA
|
|
|
|
Marso, Got it. Thanks.
This is my though assuming that Dec(2,2) for Decimals for size of 4 bytes record.
| Code: |
//SYMNAMES DD *
NUME,'0123456789'
DECM,'.'
//SYSOUT DD SYSOUT=*
//SORTLIST DD SYSOUT=*
//SORTIN DD *
8999
bbbb
299
abcc
92
0.1
5.7
9999
cefd
1
1.9
0.11
//SORTOUT DD SYSOUT=*
//SYSIN DD *
SORT FIELDS=(21,1,ZD,D,41,4,ZD,A,1,4,CH,A)
INREC IFTHEN=(WHEN=INIT,OVERLAY=(41:1,4,SQZ=(SHIFT=RIGHT))),
IFTHEN=(WHEN=INIT,
FINDREP=(STARTPOS=41,IN=C' ',OUT=C'0')),
IFTHEN=(WHEN=INIT,
FINDREP=(STARTPOS=41,IN=C'.',OUT=C'0')),
IFTHEN=(WHEN=(2,1,CH,EQ,DECM),OVERLAY=(21:C'8')),
IFTHEN=(WHEN=(1,1,SS,EQ,L(NUME)),OVERLAY=(21:C'7')),
IFTHEN=(WHEN=NONE,OVERLAY=(21:C'9'))
OUTFIL BUILD=(1,4) |
Output :
| Code: |
abcc
bbbb
cefd
0.1
0.11
1.9
5.7
1
92
299
8999
9999 |
|
|
| Back to top |
|
 |
Rohit Umarjikar
Global Moderator

Joined: 21 Sep 2010 Posts: 3109 Location: NYC,USA
|
|
|
|
| I realized , One part is missing, I shall look into it to get it fixed... |
|
| Back to top |
|
 |
Rohit Umarjikar
Global Moderator

Joined: 21 Sep 2010 Posts: 3109 Location: NYC,USA
|
|
|
|
Try this..
| Code: |
//SYMNAMES DD *
NUME,'0123456789'
//SYSOUT DD SYSOUT=*
//SORTLIST DD SYSOUT=*
//SORTIN DD *
8999
bbbb
299
abcc
92
0.1
5.7
9999
cefd
1
1.9
0.11
9999
//SYSIN DD *
//SORTOUT DD SYSOUT=*
//SYSIN DD *
SORT FIELDS=(21,1,ZD,D,41,4,ZD,A,1,4,CH,A)
INREC IFTHEN=(WHEN=(2,1,CH,EQ,C'.',AND,1,1,CH,NE,C'0'),
OVERLAY=(21:C'7',41:1,4,UFF,MUL,+100,ZD,LENGTH=5)),
IFTHEN=(WHEN=(2,1,CH,EQ,C' ',AND,1,1,SS,EQ,L(NUME)),
OVERLAY=(21:C'7',41:1,4,UFF,MUL,+100,ZD,LENGTH=5)),
IFTHEN=(WHEN=(1,1,CH,EQ,C'0',AND,2,1,CH,EQ,C'.'),
OVERLAY=(21:C'8',41:1,4,UFF,MUL,+100,ZD,LENGTH=5)),
IFTHEN=(WHEN=(1,1,SS,EQ,L(NUME)),
OVERLAY=(21:C'6',41:1,4,UFF,MUL,+100,ZD,LENGTH=5)),
IFTHEN=(WHEN=NONE,OVERLAY=(21:C'9'))
OUTFIL BUILD=(1,4,76X) |
Output:
| Code: |
abcc
bbbb
cefd
0.1
0.11
1
1.9
5.7
92
299
8999
9999
9999 |
|
|
| Back to top |
|
 |
sergeyken
Senior Member

Joined: 29 Apr 2008 Posts: 2263 Location: USA
|
|
|
|
| Code: |
8999
bbbb
299
abcc
92 <===
0.1
5.7 <===
9999
cefd
1
1.9 |
| Code: |
5.7
abcc
bbbb
cefd
0.1
1.9
1
92
299
8999
9999 |
|
|
| Back to top |
|
 |
Rohit Umarjikar
Global Moderator

Joined: 21 Sep 2010 Posts: 3109 Location: NYC,USA
|
|
|
|
TS requirements in the very first post states this clearly, so what you said will not be a possible option and even if it is possible then TS can add SQZ=(SHIFT=LEFT) as first INREC statement and I assumed it to be Dec(3,2).
| Quote: |
| • All the records are left justified |
This will take care of that but not need if they are already LEFT justified.
| Code: |
SORT FIELDS=(21,1,ZD,D,41,4,ZD,A,1,4,CH,A)
INREC IFTHEN=(WHEN=INIT,OVERLAY=(1:1,4,SQZ=(SHIFT=LEFT))),
IFTHEN=(WHEN=(2,1,CH,EQ,C'.',AND,1,1,CH,NE,C'0'),
OVERLAY=(21:C'7',41:1,4,UFF,MUL,+100,ZD,LENGTH=5)),
IFTHEN=(WHEN=(2,1,CH,EQ,C' ',AND,1,1,SS,EQ,L(NUME)),
OVERLAY=(21:C'7',41:1,4,UFF,MUL,+100,ZD,LENGTH=5)),
IFTHEN=(WHEN=(1,1,CH,EQ,C'0',AND,2,1,CH,EQ,C'.'),
OVERLAY=(21:C'8',41:1,4,UFF,MUL,+100,ZD,LENGTH=5)),
IFTHEN=(WHEN=(1,1,SS,EQ,L(NUME)),
OVERLAY=(21:C'6',41:1,4,UFF,MUL,+100,ZD,LENGTH=5)),
IFTHEN=(WHEN=NONE,OVERLAY=(21:C'9',41:C'0000'))
OUTFIL BUILD=(1,4,76X) |
|
|
| Back to top |
|
 |
|
|
 |
All times are GMT + 6 Hours |
|