2009-11-18 11 views
29

Il file di input sono record come: 8712351,8712353,8712353,8712354,8712356,8712352,8712355 8712352,8712355In che modo i duplicati possono essere rimossi da un file utilizzando COBOL?

Utilizzando COBOL ho bisogno di rimuovere i duplicati dal file sopra e scrivere un file di output. I ha scritto una semplice logica per leggere i record e scrivere su un file di output.

Dove è necessario inserire la logica di rimozione dei duplicati (ad esempio 8712353,8712352) dal file precedente. Ecco la logica del programma:

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. 

Ho risolto il file di input in ordine crescente come: 8712351,8712353,8712353,8712354,8712356,8712352,8712355,8712352,8712355 e ha funzionato, sotto è il codice modificato:

Ma supponiamo che il mio file non sia in ordine crescente o decrescente dove devo scrivere la logica di ordinamento prima di rimuovere i duplicati. si prega è possibile aggiornare il mio codice qui sotto per questo, come ho provato, ma non riuscite a fare questo se la struttura di ingresso fiel è come:

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. 
+0

WOW nuovo tag preferito! :) Domanda relativa ai dati da cui si rimuovono i duplicati: i numeri come 8712351 si verificano tutti in un intervallo relativamente compatto, ad esempio 8700000-8800000? Oppure i numeri possono variare da 1-N su un intervallo enorme? –

risposta

2

Quando Organization è Sequential, il record eliminato è l'ultimo record letto. L'istruzione Delete è valida solo quando l'ultima operazione sul file è un'istruzione Read corretta. In caso contrario, il Delete restituisce un valore File Status di 43. Perché un Delete non può restituire File Status valori che iniziano con un 2 quando il file è Open con Sequential accesso, codifica Invalid Key su tale Delete non è permesso.

Quando si seleziona Dynamic o Random accesso per il file, lo statment Delete, come il Rewrite, diventa un po 'meno restrittiva. Il record cancellato non ha bisogno di aver letto bene in precedenza. Basta inserire le informazioni primarie Key nella descrizione del record per il fle ed emettere l'istruzione Delete. Se il record non esiste, viene restituito un File Status di 23 e esiste una condizione Invalid Key.

Da pagina 274 del

Sams Teach Yourself COBOL in 24 Hours

pagina 274 (che ho appena rispolverato giù da fuori la mia libreria). Quindi nel tuo caso dovrai presumibilmente impostare i tuoi record per essere ordinati per INPUTFILEID, fare un record mentre passi attraverso le occorrenze di un dato INPUTFILEID dopo la sua prima occorrenza, e Delete di conseguenza (dopo averlo scritto sul tuo file di output) .

1

Se si ordina il file con un ordinamento esterno prima di leggerlo nel programma cobol, è possibile rimuovere i duplicati con la parola chiave SORT EQUALS. Se si ordina il file prima del programma cobol e non si eliminano i duplicati, una semplice istruzione IF e un campo di salvataggio consentono di eliminare i duplicati.

Impostare un campo di salvataggio INPUTFILEID. Subito dopo la lettura ....IF inputfileid equal inputfileid-save read again se non scrive ... dopo la scrittura move inputfileid su inputfileid-save. Dovrai interrompere il rendimento attuale per farlo.

Se non comprendere appieno quello che sto dicendo e vi aiuterà a cambiare il codice fammelo sapere

5

Infine ha funzionato. Qui è il codice

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

sort è standard per questi lavori os-intorno a seguire principio DRY, ingranaggi -t per separatore e -u per unici. È C.

Problemi correlati