home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
drtree.zip
/
DIRMATCH.CMD
next >
Wrap
OS/2 REXX Batch file
|
1994-02-17
|
14KB
|
296 lines
/* Program DIRMATCH.CMD rev 1.0 1/1/94 by Conrad W. Clark 70544,760 */
/* you are licensed to use, copy, and redistribute as long */
/* as the 1st 5 lines of this file remain as is, and you and */
/* subsequent licensees agree that this program is distributed */
/* as is, use and consequences are solely the responsibility of the user. */
/* rexx pgm to find file name matches in two directory or subdir structures */
/* the program is useful for finding obsolete DLLs, or mislaid or duplicate programs */
/* This program is distributed as is, use and consequences are solely the responsibility */
/* of the user. */
/* Developed and tested under OS/2 2.1. It should work with OS/2 2.0 */
/* */
/* Use of Program: */
/* [d:\]dirmatch[.cmd] filestructure targetstructure [prn:|stdout:|filename] [string]*/
/* dirmatch ? displays online help */
/* for example, if dirmatch.cmd is in e:\cmd, */
/* */
/* e:\cmd\dirmatch c:\os2\dll\*.* c:\describe\dll\*.* will find files with matching */
/* names in the dll directories, and their subdirectories, and display matching pairs */
/* */
/* e:\cmd\dirmatch c:\os2\dll\*.* c:\describe\dll\*.* prn: will find files with matching */
/* names, display matched pairs, and print target matches */
/* */
/* e:\cmd\dirmatch c:\os2\dll\*.* c:\describe\dll\*.* prn: xyz will find files with matching */
/* names if they include the string xyz, display matched pairs, and print target matches */
/* note that if the 3rd arg is a file, and it exists, it will be appended to. */
/* note that if a 4th arg string is specified, you must specify the 3rd arg, since the */
/* filter expects to lineout lines in the targetfiles.i containing xyz */
/* the use of shell sorted source and targets give much better performance with large */
/* numbers of files. for example, a 233 source by 1324 target took 15 mins unsorted, */
/* 170 seconds sorted */
/* */
/* insert additional filters or selection logic at the comment INSERT FILTERS HERE */
/* */
/* explain variables */
/* */
cr = d2c(13) /* carriage return */
bs = d2c(8) /* backspace */
lf = d2c(10) /* line feed */
/* filespec is 1st argument, a directory path spec, including wildcards */
/* targetspec is 2nd argument, a directory path spec, including wildcards */
/* outfile is optional 3rd argument, on output device or file name */
/* suggested values prn: for printer, lpt1: for printer, stdout: for display, or a filename */
/* stringinfile is optional 4th argument, to select only files containing that string */
/* files.j is an array of file names from SysFileTree, of source files. */
/* files.0 is number of files */
/* targetfiles.i is target file array, similar to files.j */
/* structime is a timestamp of elapsed time */
/* numbermatches is number of file matches found, = number of records in 3rd arg's file */
/* istart is place pointer for target file array */
/* j is placepointer for source file array */
/* i is transient index into target file array */
/* fileposition points to \ just before file name (or : after drive letter in filter) */
/* sourceflen is length of current source file name (without path info) */
/* sourcestring and targetstring are the file names (not including path, eg name.dat ) */
/* matchcorrection is used to back up the target placeholder, to get matches of dups */
/* linematch.klm is array size in .0 containing lines in target containing stringinfile string */
/* fullfilename is file name including drive and path for string filter SysFileSearch */
/* result is a rexx special variable for function return codes, if 0, ok */
/* for documentation of the shell sort variables, see the referenced textbook */
starttime = time('R') /* reset elapsed timer */
call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs' /* register all utility functions */
call SysLoadFuncs
filespec = '' /* initialize args to null strings */
targetspec = ''
outfile = ''
stringinfile = ''
arg filespec targetspec outfile stringinfile /* get the two structures to match */
/* outfile is optional file or printer name */
/* for list of target files matching */
/* stringinfile is a string, select only targets containing it */
if filespec = '' then
do
say 'ERROR, missing source directory structure'
exit
end
if filespec = '?' then /* display online help */
do
say 'Program DIRMATCH.CMD rev 1.0 1/1/94 by Conrad W. Clark 70544,760'
say 'A rexx pgm to find file name matches in two directory or subdir structures,'
say 'useful for finding obsolete DLLs, or mislaid or duplicate programs.'
say ' '
say ' Use of Program:'
say ' [d:\]dirmatch[.cmd] filestruct targetstruct [prn:|stdout:|filename] [string]'
say ' '
say ' for example, if dirmatch.cmd is in e:\cmd,'
say ' e:\cmd\dirmatch c:\os2\dll\*.* c:\describe\dll\*.* will find files'
say ' with matching names in the dll directories, and their subdirectories,'
say ' and display matching pairs'
say ' e:\cmd\dirmatch c:\os2\dll\*.* c:\describe\dll\*.* prn: will find files'
say ' with matching names, display matched pairs, and print target matches'
say ' e:\cmd\dirmatch c:\os2\dll\*.* c:\describe\dll\*.* prn: xyz will find files'
say ' with matching names if they include the string xyz, display matched pairs,'
say ' and print target matches'
say ' '
say 'If the 3rd arg is a file, and it already exists, it will be appended to.'
say 'Note that if a 4th arg string is specified, you must specify the 3rd arg,'
say 'since the filter expects to lineout lines in the targetfiles.i containing xyz.'
say 'Internal shell sorts improve performance with numerous files.'
exit
end
if targetspec = '' then
do
say 'ERROR, missing target directory structure'
exit
end
say 'filespec is' filespec
call SysFileTree filespec, 'files.', 'sf' /* get files in first dir structure */
/* including subdirectories */
if result <> 0 then
do
say 'source file ERROR, SysFileTree result = ' result
say 'result 2 is not enough memory'
exit
end
say 'number input files is ' files.0
say 'match to target filespec'
say 'target is ' targetspec
call charout cr||lf
call SysFileTree targetspec, 'targetfiles.', 'sf' /* get files in target dir structure */
if result <> 0 then
do
say 'target file ERROR, SysFileTree result = ' result
say 'result 2 is not enough memory'
exit
end
say 'number target files is ' targetfiles.0
structime = time('E')
say 'get structures timestamp = ' structime
call sortfiles /* sort input files */
call sorttargets /* sort target files */
call charout 'stdout:', cr
numbermatches = 0 /* to say how many matched */
istart = 1 /* initially, start at start of targets */
/* files. and targetfiles. are sorted ascending */
do j = 1 to files.0 /* for each file, compare to remaining target files */
fileposition = lastpos('\',files.j) /* last \ is just before file name */
sourceflen = length(files.j) - fileposition
sourcestring = right(files.j, sourceflen)
call charout "stdout:", sourcestring /* say file.j as heartbeat */
gotmatch = 0
matchcorrection = 0 /* correct for dups in files. */
do i = istart to targetfiles.0
fileposition = lastpos('\',targetfiles.i)
targetstring = right(targetfiles.i,(length(targetfiles.i)-fileposition))
if sourcestring = targetstring then /* matching filenames */
do ilinematch = 1 /* counter for leaving if no string match */
call charout "stdout:",cr||lf
/* INSERT FILTERS HERE */
/* string match filter (not case sensitive) */
if stringinfile <>'' then /* if a string to find is specified */
/* accept target if it contains 4th arg string */
do
gotmatch = 1 /* got output, do not backspace */
fileposition = lastpos(':',targetfiles.i) /* -> : after drive letter */
/* get file name including drive and path */
fullfilename = right(targetfiles.i,(length(targetfiles.i)-fileposition + 2))
call SysFileSearch stringinfile, fullfilename, linematch
if result <> 0 then
do
say 'source file ERROR, SysFileSearch result = ' result
say 'result 2 is not enough memory'
say 'result 3 is error opening file'
exit
end
if linematch.0 = 0 then leave ilinematch /* no string match */
do klm = 1 to linematch.0 /* print lines with string match */
do
call lineout outfile, linematch.klm
if result <> 0 then
do
say 'source file ERROR, lineout result = ' result
say 'check 3rd argument, printer status, file name'
exit
end
end
end
end
/* end string match filter */
say 'file is ' files.j
say 'target is ' targetfiles.i
numbermatches = numbermatches + 1
matchcorrection = matchcorrection + 1
/* if a third argument, output target line to file or printer (prn:) */
if outfile <> '' then
do
call lineout outfile, targetfiles.i
if result <> 0 then
do
say 'source file ERROR, lineout result = ' result
say 'check 3rd argument, printer status, file name'
exit
end
end
gotmatch = 1 /* got output, do not backspace */
leave ilinematch /* must explicitly leave if dummy loop variable */
end
if sourcestring < targetstring then
do
istart = i - matchcorrection /* recheck in case of dups in files. */
leave i /* do not recheck if too small */
end
end
if gotmatch = 0 then /* maintain heartbeat */
do
call charout "stdout:",bs
do k = 1 to (sourceflen - 1) /*reposition cursor at start of heartbeat */
call charout 'stdout:', ' '||bs||bs
end
call charout "stdout:",' '||bs
end
end
endtime = time('E')
say 'get structures timestamp = ' structime
say 'sort input files timestamp = ' sortintime
say 'sort target files timestamp = ' sorttartime
say 'completion timestamp = ' endtime
say 'number of matches = ' numbermatches
exit
/**********************/
/* */
/* SORT ROUTINES */
/* */
/**********************/
sortfiles: /* shell sort of input files */
/* use shell sort (Sedgewick:Algorithms 1984) */
/* since many directories may be already ordered */
h = 1
do until h>files.0
h = 3*h+1
end /* do */
do forever until h = 1
h = h % 3 /* integer result */
do i = h+1 to files.0
v = files.i
fileposition = lastpos('\',files.i)+1 /* last \ is just before file name */
j = i
k = j-h
key1 = substr(v,fileposition)
/* say 'key1 = ' key1 */
do while substr(files.k,(lastpos('\',files.k)+1)) > key1
files.j = files.k
j = j-h
k = j-h
if j <= h then leave
end
files.j = v
end /* do */
end /* do forever */
sortintime = time('E')
say 'sort input files timestamp = ' sortintime
return
sorttargets: /* shell sort target files */
/* use shell sort (Sedgewick:Algorithms 1984) */
/* since many directories may be already ordered */
h = 1
do until h>targetfiles.0
h = 3*h+1
end /* do */
do forever until h = 1
h = h % 3 /* integer result */
do i = h+1 to targetfiles.0
v = targetfiles.i
j = i
k = j-h
fileposition = lastpos('\',targetfiles.i)+1 /* last \ is just before file name */
key1 = substr(v,fileposition)
/* say 'key1 = ' key1 */
do while substr(targetfiles.k,(lastpos('\',targetfiles.k)+1)) > key1
targetfiles.j = targetfiles.k
j = j-h
k = j-h
if j <= h then leave
end
targetfiles.j = v
end /* do */
end /* do forever */
sorttartime = time('E')
say 'sort target files timestamp = ' sorttartime
return