如何使用Sort查找字段重复字符?IFTHEN+Overlay方案失效求助
使用DFSORT/ICETOOL查找字段中的重复字符
需求描述
需要从每条记录的名字字段中提取出重复出现的字符,去重后以空格分隔追加到记录末尾。
输入数据:
----+----1----+----2----+ 0112 CHENNAI 0104 HARRISON 0105 HARINI KRISHNAN
期望输出:
----+----1----+----2----+----3----+ 0112 CHENNAI N 0104 HARRISON R 0105 HARINI KRISHNAN H A R I N
解决方案:基于ICETOOL的拆分-统计-合并流程
使用DFSORT的ICETOOL工具,通过拆分字符、统计重复、合并结果三个步骤实现需求,以下是完整JCL示例:
//SORTJOB JOB (ACCT),'FIND DUPLICATE CHARS',CLASS=A,MSGCLASS=X //ICETOOL EXEC PGM=ICETOOL //TOOLMSG DD SYSOUT=* //DFSMSG DD SYSOUT=* //IN DD * ----+----1----+----2----+ 0112 CHENNAI 0104 HARRISON 0105 HARINI KRISHNAN //TEMPSPLT DD DSN=&&TEMPSPLT,UNIT=SYSDA,SPACE=(CYL,(1,1)),DISP=(,PASS) //TEMPCOUNT DD DSN=&&TEMPCOUNT,UNIT=SYSDA,SPACE=(CYL,(1,1)),DISP=(,PASS) //OUT DD SYSOUT=* //TOOLIN DD * * 1. 拆分名字字段为单字符记录 SPLIT FROM(IN) TO(TEMPSPLT) ON(6,20) EVERY(1) USING(CTL1) * 2. 统计每个键+字符的出现次数,仅保留重复字符 COUNT FROM(TEMPSPLT) TO(TEMPCOUNT) KEY(1,5,CH,5) KEY(6,1,CH,1) USING(CTL2) * 3. 合并原记录与重复字符,整理输出格式 MERGE FROM(IN,TEMPCOUNT) TO(OUT) USING(CTL3) /* //CTL1CNTL DD * * 保留原记录前5位作为唯一键,提取单个字符 INREC BUILD=(1:1,5, 6:6,1, 7:X) /* //CTL2CNTL DD * * 过滤掉出现次数≤1的字符,保留重复项 OUTFIL FNAMES=TEMPCOUNT, INCLUDE=(8,1,ZD,GT,1), BUILD=(1:1,5, 6:6,1, 7:X) /* //CTL3CNTL DD * * 将同一键下的重复字符拼接至指定位置 INREC IFTHEN=(WHEN=GROUP, BEGIN=(1,5,CH,NE,1,5,CH), PUSH=(27:6,1)), IFTHEN=(WHEN=INIT, * 整理空格,将连续空格替换为单个空格 OVERLAY=(27:27,20,FINDREP=(IN=C' ',OUT=C' '), 27:27,20,FINDREP=(IN=C' ',OUT=C' '))) * 输出最终格式,保留原记录前26位+拼接的重复字符 OUTFIL FNAMES=OUT, REMOVECC, BUILD=(1:1,26, 27:27,20) /*
各阶段说明
拆分阶段(SPLIT):
将每条原记录的名字字段(第6位开始,长度20)拆分为20条小记录,每条包含原记录的前5位唯一键和一个单个字符,为后续统计做准备。统计阶段(COUNT):
按「键+字符」分组统计出现次数,仅保留出现次数大于1的字符(即重复字符),过滤掉只出现一次的字符。合并阶段(MERGE):
使用WHEN=GROUP将同一键下的所有重复字符拼接至记录的第27位开始位置,再通过FINDREP整理空格,确保重复字符之间用单个空格分隔,最终输出符合要求的格式。
注意事项
- 若名字字段长度不是20,需修改
SPLIT中的ON(6,20)参数及相关BUILD语句的长度。 - 若原记录的唯一键不是前5位,需调整
KEY参数的位置和长度。 - 若不需要统计空格,可在
CTL2CNTL的INCLUDE中添加AND(6,1,CH,NE,C' ')过滤空格。
内容的提问来源于stack exchange,提问作者Angel
相关产品推荐
相关产品推荐

