home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
pub
/
scripts
/
ckermit
/
merge
< prev
next >
Wrap
Text File
|
2020-01-01
|
3KB
|
66 lines
#!/usr/local/bin/kermit +
;
; m e r g e
;
; Merges any number of files, each of which is already sorted in ascending
; order, into a new file that is also sorted in ascending order. Blank
; lines are discarded. The result file is sent to standard output. The
; files may be of different lengths, including empty. UNIX usage, in which
; standard output is redirected to a file:
;
; merge file1 file2 file3 ... > output-file
;
; Requires: C-Kermit 7.0 or later.
; Illustrates: FOPEN/FREAD/FCLOSE operating on multiple files at once.
;
; Note syntax of comparison at bottom of FOR loop. The record array
; reference is accessed through \fcontents() to prevent unwanted processing
; of backslashes in the record, and enclosed in braces to preserve leading
; and trailing spaces.
;
; In this example, the sort key is the whole record. To use other sort keys
; or orders, modify the comparison statement accordingly. Other modifications
; would be needed for discarding duplicate records, flagging sequence errors
; in source files, etc.
;
; Author: F. da Cruz, the Kermit Project, Columbia University, July 1999
;
local \%i \%n \&c[] \&r[] ; Local variables
.\%n ::= (\v(argc)-1) ; Number of files from command line
dcl \&c[\%n] ; Channel numbers for each file
dcl \&r[\%n] ; Current record from each file
for \%i 1 \%n 1 { ; Loop through command-line arguments
.\&c[\%i] = -1 ; Remember which files are not open
fopen /read \&c[\%i] \&_[\%i] ; Try to open this one
}
while 1 { ; Loop till done
.\%k = -1 ; Index of next output record
set flag off ; No records yet
for \%i 1 \%n 1 { ; For each file...
if < \&c[\%i] 0 continue ; Skip this one if it's not open
while not def \&r[\%i] { ; Skip blank lines
if \f_eof(\&c[\%i]) { ; If at end of file
fclose \&c[\%i] ; close this file
.\&c[\%i] = -1 ; and mark it as closed
break
}
fread \&c[\%i] \&r[\%i] ; Otherwise read a record
}
if < \&c[\%i] 0 continue ; Next file if this file closed above
if not flag { ; First record this round
.\%k := \%i ; Remember its index
set flag on ; Not first record any more
continue ; On to next file
}
; Lexically compare this record with the current smallest record
if ( llt {\fcont(\&r[\%i])} {\fcont(\&r[\%k])} ) .\%k := \%i
}
if ( < \%k 0 ) break ; If no more records we're done.
echo \&r[\%k] ; Otherwise output this record
undef \&r[\%k] ; and force it to be replaced.
}
exit 0