Как можно удалить дубликаты из файла с помощью COBOL?
Входной файл имеет записи как: 8712351,8712353,8712353,8712354,8712356,8712352,8712355 8712352,8712355
Используя COBOL мне нужно удалить дубликаты из вышеуказанного файла и записать в выходной файл. Я написал простую логику для чтения записей и записи в выходной файл.
Куда мне нужно поместить логику удаления дубликатов (скажем,8712353,8712352) из приведенного выше файла. Вот логика программы:
IDENTIFICATION DIVISION.
PROGRAM-ID.RemoveDup.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUTFILEDUP ASSIGN TO 'C:\Cobol\INPUTFILEDUP.txt'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT OUTFILEDUP ASSIGN TO 'C:\Cobol\OUTFILEDUP.txt'
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD INPUTFILEDUP.
01 INPUTFILEDUPREC.
88 EOFINPUTFILEDUP VALUE HIGH-VALUES.
02 INPUTFILEID PIC 9(07).
FD OUTFILEDUP.
01 OUTFILEDUPREC PIC 9(07).
WORKING-STORAGE SECTION.
77 WS-VARIABLE PIC 9(09).
77 REC-NOT-MATCH PIC 9(01).
77 CUR-VARIABLE PIC 9(09).
PROCEDURE DIVISION.
BEGIN.
OPEN INPUT INPUTFILEDUP
OPEN OUTPUT OUTFILEDUP
READ INPUTFILEDUP
AT END SET EOFINPUTFILEDUP TO TRUE
END-READ
PERFORM UNTIL (EOFINPUTFILEDUP)
WRITE OUTFILEDUPREC FROM INPUTFILEID
READ INPUTFILEDUP
AT END SET EOFINPUTFILEDUP TO TRUE
PERFORM UNTIL (EOFINPUTFILEDUP)
END-READ
END-PERFORM
CLOSE INPUTFILEDUP
CLOSE OUTFILEDUP
STOP RUN.
Я отсортировал входной файл в порядке возрастания как: 8712351,8712353,8712353,8712354,8712356,8712352,8712355,8712352,8712355 И это сработало, ниже приведен модифицированный код:
Но предположим, что если мой файл находится не в порядке возрастания или убывания, где мне нужно написать логику сортировки перед удалением дубликатов. пожалуйста, вы можете обновить мой приведенный ниже код для этого, как я пытался, но безуспешно, если структура входного поля имеет вид:
8712351,8712353,8712353,8712354,8712356,8712352,8712355,8712352,8712355
IDENTIFICATION DIVISION.
PROGRAM-ID.RemoveDup2.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUTFILEDUP ASSIGN TO 'C:\Cobol\INPUTFILEDUP.txt'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT OUTFILEDUP ASSIGN TO 'C:\Cobol\OUTFILEDUP.txt'
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD INPUTFILEDUP.
01 INPUTFILEDUPREC.
88 EOFINPUTFILEDUP VALUE HIGH-VALUES.
02 INPUTFILEID PIC 9(07).
FD OUTFILEDUP.
01 OUTFILEDUPREC PIC 9(07).
WORKING-STORAGE SECTION.
77 WS-VARIABLE PIC 9(09) VALUE ZERO.
77 REC-NOT-MATCH PIC 9(01).
77 CUR-VARIABLE PIC 9(7) VALUE ZERO.
PROCEDURE DIVISION.
BEGIN.
OPEN INPUT INPUTFILEDUP
OPEN OUTPUT OUTFILEDUP
READ INPUTFILEDUP
AT END SET EOFINPUTFILEDUP TO TRUE
END-READ
PERFORM UNTIL (EOFINPUTFILEDUP)
IF INPUTFILEID NOT EQUAL TO WS-VARIABLE
MOVE INPUTFILEID TO WS-VARIABLE
WRITE OUTFILEDUPREC FROM INPUTFILEID
READ INPUTFILEDUP
AT END SET EOFINPUTFILEDUP TO TRUE
PERFORM UNTIL (EOFINPUTFILEDUP)
ELSE
DISPLAY "dUPLICATE FOUND" INPUTFILEID
READ INPUTFILEDUP
AT END SET EOFINPUTFILEDUP TO TRUE
END-READ
END-PERFORM
CLOSE INPUTFILEDUP
CLOSE OUTFILEDUP
STOP RUN.
4 ответа
Наконец-то это сработало. Вот код
IDENTIFICATION DIVISION.
PROGRAM-ID.RemoveDup2.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUTFILEDUP ASSIGN TO 'C:\Cobol\INPUTFILEDUP.txt'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT OUTFILEDUP ASSIGN TO 'C:\Cobol\OUTFILEDUP.txt'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT WorkFile ASSIGN TO "WORK.TMP".
DATA DIVISION.
FILE SECTION.
FD INPUTFILEDUP.
01 INPUTFILEDUPREC.
88 EOFINPUTFILEDUP VALUE HIGH-VALUES.
02 INPUTFILEID PIC 9(07).
FD OUTFILEDUP.
01 OUTFILEDUPREC PIC 9(07).
SD WorkFile.
01 WORKREC.
02 WINPUTFILEID PIC 9(07).
WORKING-STORAGE SECTION.
77 WS-VARIABLE PIC 9(09) VALUE ZERO.
77 REC-NOT-MATCH PIC 9(01).
77 CUR-VARIABLE PIC 9(7) VALUE ZERO.
PROCEDURE DIVISION.
BEGIN.
SORT WorkFile ON ASCENDING KEY WINPUTFILEID
USING INPUTFILEDUP GIVING INPUTFILEDUP
OPEN INPUT INPUTFILEDUP
OPEN OUTPUT OUTFILEDUP
READ INPUTFILEDUP
AT END SET EOFINPUTFILEDUP TO TRUE
END-READ
PERFORM UNTIL (EOFINPUTFILEDUP)
IF INPUTFILEID NOT EQUAL TO WS-VARIABLE
MOVE INPUTFILEID TO WS-VARIABLE
WRITE OUTFILEDUPREC FROM INPUTFILEID
READ INPUTFILEDUP
AT END SET EOFINPUTFILEDUP TO TRUE
PERFORM UNTIL (EOFINPUTFILEDUP)
ELSE
DISPLAY "DUPLICATE FOUND " INPUTFILEID
READ INPUTFILEDUP
AT END SET EOFINPUTFILEDUP TO TRUE
END-READ
END-PERFORM
CLOSE INPUTFILEDUP
CLOSE OUTFILEDUP
STOP RUN.
Когда Organization
является Sequential
, удаленная запись является последней прочитанной записью. Delete
оператор действителен только тогда, когда последняя операция с файлом успешна Read
заявление. Если нет, то Delete
возвращает File Status
значение 43. Потому что Delete
не может вернуться File Status
значения, начинающиеся с 2, когда файл Open
с Sequential
Доступ, кодирование Invalid Key
на такой Delete
не допускается.
когда Dynamic
или же Random
доступ выбран для файла, Delete
устав, как и Rewrite
становится немного менее строгим. Удаляемая запись не обязательно должна быть прочитана ранее. Просто заполните основной Key
информация в описании записи для фл и выдачи Delete
заявление. Если запись не существует, File Status
из 23 возвращается и Invalid Key
условие существует.
Со страницы 274
Самс научи себя коболу за 24 часа
страница 274 (которую я только что отряхнул со своей книжной полки). Таким образом, в вашем случае вы, вероятно, настроите свои записи для сортировки по INPUTFILEID
сделайте запись, как вы проходите через случаи данного INPUTFILEID
мимо его первого появления, и Delete
соответственно (после того, как вы записали его в свой выходной файл).
Если вы отсортируете файл с помощью внешней сортировки перед чтением его в программе cobol, вы можете удалить дубликаты с помощью ключевого слова SORT EQUALS. Если вы сортируете файл до программы на cobol и не удаляете дубликаты, тогда простое выражение IF и поле для сохранения позволят вам удалить дубликаты.
Установите поле сохранения INPUTFILEID. Сразу после чтения.... ЕСЛИ inputfileid равен inputfileid-save, прочитайте еще раз, если не запись... после записи переместите inputfileid в inputfileid-save. Вам придется разбить текущее исполнение, чтобы сделать это.
Если вы не до конца понимаете, о чем я говорю, и поможете изменить код, просто дайте мне знать
Для этих заданий os-close стандартным является sort, следуя принципу DRY, gears -t для разделителя и -u для уникальных. Это C.