Сравните два файла и запишите его в файлы "match" и "nomatch"
У меня есть два входных файла, каждый с длиной 5200 байт. Для сравнения обоих файлов используется семибайтовый ключ. Если есть совпадение, его нужно записать в файл "совпадения", но при записи в файл совпадения мне нужно несколько полей из infile1
и все остальные поля из infile2
,
Если совпадений нет, напишите no match
файл.
Можно ли сделать это в sort
? Я знаю, что это легко сделать с помощью программы COBOL, но просто хочу знать, SORT/ICETOOL/Easytrieve Plus (EZTPA00)
,
5 ответов
Поскольку 12 200 человек посмотрели на этот вопрос и не получили ответа:
DFSORT и SyncSort являются основными продуктами для сортировки мэйнфреймов. Их контрольные карты имеют много общего и некоторые отличия.
JOINKEYS FILE=F1,FIELDS=(key1startpos,7,A)
JOINKEYS FILE=F2,FIELDS=(key2startpos,7,A)
JOIN UNPAIRED,F1,F2
REFORMAT FIELDS=(F1:1,5200,F2:1,5200)
SORT FIELDS=COPY
"JOINKEYS" состоит из трех задач. Подзадача 1 - это первые СОЕДИНЕНИЯ. Подзадача 2 является вторым JOINKEYS. Основная задача следует и где обрабатываются объединенные данные. В приведенном выше примере это простая операция COPY. Присоединенные данные будут просто записаны в SORTOUT.
Оператор JOIN определяет, что наряду с сопоставленными записями записи UNPAIRED F1 и F2 должны быть представлены главной задаче.
Оператор REFORMAT определяет запись, которая будет представлена главной задаче. Более эффективный пример, представляющий, что три поля требуются от F2, это:
REFORMAT FIELDS=(F1:1,5200,F2:1,10,30,1,5100,100)
Каждое из полей на F2 определено с начальной позицией и длиной.
Запись, которая затем обрабатывается главной задачей, имеет длину 5311 байт, а на поля из F2 можно ссылаться как 5201,10,5211,1,5212,100 с записью F1, равной 1,5200.
Лучший способ добиться того же - уменьшить размер F2 с помощью JNF2CNTL.
//JNF2CNTL DD *
INREC BUILD=(207,1,10,30,1,5100,100)
Некоторые установки SyncSort не поддерживают JNF2CNTL, и даже там, где это поддерживается (начиная с Syncsort MFX для z/OS версии 1.4.1.0 и далее), он не задокументирован SyncSort. Для пользователей 1.3.2 или 1.4.0 доступно обновление от SyncSort для обеспечения поддержки JNFnCNTL.
Следует отметить, что JOINKEYS по умолчанию сортирует данные с опцией EQUALS. Если данные для файла JOINKEYS уже находятся в последовательности, следует указать SORTED. Для DFSORT также можно указать NOSEQCHK, если проверка последовательности не требуется.
JOINKEYS FILE=F1,FIELDS=(key1startpos,7,A),SORTED,NOSEQCHK
Хотя запрос странный, так как исходный файл не может быть определен, все несопоставленные записи должны идти в отдельный выходной файл.
В DFSORT есть маркер соответствия, указанный с помощью? в РЕФОРМАТ:
REFORMAT FIELDS=(F1:1,5200,F2:1,10,30,1,5100,100,?)
Это увеличивает длину записи REFORMAT на один байт.? может быть указан в любом месте записи REFORMAT, и не должен быть указан.? разрешается DFSORT для: B, данные получены из обоих файлов; 1, непревзойденная запись от F1; 2, непревзойденная запись из F2.
SyncSort не имеет маркера совпадения. Отсутствие или наличие данных в записи REFORMAT должно определяться значениями. Выберите байт в обеих входных записях, которые не могут содержать конкретное значение (например, в пределах числа выбрать нечисловое значение). Затем укажите это значение в качестве символа FILL в REFORMAT.
REFORMAT FIELDS=(F1:1,5200,F2:1,10,30,1,5100,100),FILL=C'$'
Если позиция 1 на F1 не может иметь "$" и позиция 20 на F2 тоже не может, то эти две позиции могут быть использованы для установления результата матча. Вся запись может быть проверена в случае необходимости, но затрачивает больше процессорного времени.
Очевидное требование заключается в том, чтобы все несопоставленные записи из F1 или F2 записывались в один файл. Для этого потребуется оператор REFORMAT, который включает обе записи во всей их полноте:
DFSORT, выводить несопоставленные записи:
REFORMAT FIELDS=(F1:1,5200,F2:1,5200,?)
OUTFIL FNAMES=NOMATCH,INCLUDE=(10401,1,SS,EQ,C'1,2'),
IFTHEN=(WHEN=(10401,1,CH,EQ,C'1'),
BUILD=(1,5200)),
IFTHEN=(WHEN=NONE,
BUILD=(5201,5200))
SyncSort, выводит несопоставленные записи:
REFORMAT FIELDS=(F1:1,5200,F2:1,5200),FILL=C'$'
OUTFIL FNAMES=NOMATCH,INCLUDE=(1,1,CH,EQ,C'$',
OR,5220,1,CH,EQ,C'$'),
IFTHEN=(WHEN=(1,1,CH,EQ,C'$'),
BUILD=(1,5200)),
IFTHEN=(WHEN=NONE,
BUILD=(5201,5200))
Кодирование для SyncSort также будет работать с DFSORT.
Получить сопоставленные записи легко.
OUTFIL FNAMES=MATCH,SAVE
SAVE гарантирует, что все записи, не написанные другим OUTFIL, будут записаны здесь.
Требуется некоторое переформатирование, чтобы в основном выводить данные из F1, но выбирать некоторые поля из F2. Это будет работать для DFSORT или SyncSort:
OUTFIL FNAMES=MATCH,SAVE,
BUILD=(1,50,10300,100,51,212,5201,10,263,8,5230,1,271,4929)
Все с произвольными началами и длинами:
DFSORT
JOINKEYS FILE=F1,FIELDS=(1,7,A)
JOINKEYS FILE=F2,FIELDS=(20,7,A)
JOIN UNPAIRED,F1,F2
REFORMAT FIELDS=(F1:1,5200,F2:1,5200,?)
SORT FIELDS=COPY
OUTFIL FNAMES=NOMATCH,INCLUDE=(10401,1,SS,EQ,C'1,2'),
IFTHEN=(WHEN=(10401,1,CH,EQ,C'1'),
BUILD=(1,5200)),
IFTHEN=(WHEN=NONE,
BUILD=(5201,5200))
OUTFIL FNAMES=MATCH,SAVE,
BUILD=(1,50,10300,100,51,212,5201,10,263,8,5230,1,271,4929)
Syncsort
JOINKEYS FILE=F1,FIELDS=(1,7,A)
JOINKEYS FILE=F2,FIELDS=(20,7,A)
JOIN UNPAIRED,F1,F2
REFORMAT FIELDS=(F1:1,5200,F2:1,5200),FILL=C'$'
SORT FIELDS=COPY
OUTFIL FNAMES=NOMATCH,INCLUDE=(1,1,CH,EQ,C'$',
OR,5220,1,CH,EQ,C'$'),
IFTHEN=(WHEN=(1,1,CH,EQ,C'$'),
BUILD=(1,5200)),
IFTHEN=(WHEN=NONE,
BUILD=(5201,5200))
OUTFIL FNAMES=MATCH,SAVE,
BUILD=(1,50,10300,100,51,212,5201,10,263,8,5230,1,271,4929)
//STEP01 EXEC SORT90MB
//SORTJNF1 DD DSN=INPUTFILE1,
// DISP=SHR
//SORTJNF2 DD DSN=INPUTFILE2,
// DISP=SHR
//SORTOUT DD DSN=MISMATCH_OUTPUT_FILE,
// DISP=(,CATLG,DELETE),
// UNIT=TAPE,
// DCB=(RECFM=FB,BLKSIZE=0),
// DSORG=PS
//SYSOUT DD SYSOUT=*
//SYSIN DD *
JOINKEYS FILE=F1,FIELDS=(1,79,A)
JOINKEYS FILE=F2,FIELDS=(1,79,A)
JOIN UNPAIRED,F1,ONLY
SORT FIELDS=COPY
/*
Несмотря на то, что этот вопрос был опубликован очень давно, я хочу ответить, так как он может помочь другим. Это можно легко сделать с помощью JOINKEYS
в ОДНОМ шаге. Вот псевдокод:
- Код
JOINKEYS PAIRED(implicit)
и получить обе записи через переформатирование поданных. Если нет совпадений ни с одним из файлов, добавьте / префикс какого-нибудь специального символа скажем'$'
- Сравните через IFTHEN для
'$'
, если существует, то у него нет парной записи, она будет записана в непарный файл и помещена в парный файл.
Пожалуйста, ответьте на любые вопросы.
Я использовал JCL около 2 лет назад, поэтому не могу написать код для вас, но вот идея;
- Есть 2 шага
- Первый шаг будет иметь ICETOOl, где вы можете записать соответствующие записи в соответствующий файл.
- Во-вторых, вы можете написать файл для несоответствия, используя SORT/ICETOOl или просто файловые операции.
снова я прошу прощения за решение без кода, но я потерял связь через 2 года +
В Eztrieve это действительно просто, ниже приведен пример того, как вы могли бы его кодировать:
//STEP01 EXEC PGM=EZTPA00
//FILEA DD DSN=FILEA,DISP=SHR
//FILEB DD DSN=FILEB,DISP=SHR
//FILEC DD DSN=FILEC.DIF,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(100,50),RLSE),
// UNIT=PRMDA,
// DCB=(RECFM=FB,LRECL=5200,BLKSIZE=0)
//SYSOUT DD SYSOUT=*
//SRTMSG DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
FILE FILEA
FA-KEY 1 7 A
FA-REC1 8 10 A
FA-REC2 18 5 A
FILE FILEB
FB-KEY 1 7 A
FB-REC1 8 10 A
FB-REC2 18 5 A
FILE FILEC
FILE FILED
FD-KEY 1 7 A
FD-REC1 8 10 A
FD-REC2 18 5 A
JOB INPUT (FILEA KEY FA-KEY FILEB KEY FB-KEY)
IF MATCHED
FD-KEY = FB-KEY
FD-REC1 = FA-REC1
FD-REC2 = FB-REC2
PUT FILED
ELSE
IF FILEA
PUT FILEC FROM FILEA
ELSE
PUT FILEC FROM FILEB
END-IF
END-IF
/*