Xref: utzoo comp.sys.amiga.tech:17595 comp.lang.rexx:389 Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!olivea!tymix!tardis!jms From: jms@tardis.Tymnet.COM (Joe Smith) Newsgroups: comp.sys.amiga.tech,comp.lang.rexx Subject: Re: Parsing filenames with blanks inside Rexx Summary: showdir() takes 3 args! Message-ID: <1406@tardis.Tymnet.COM> Date: 8 Jan 91 09:56:01 GMT References: <1400@tardis.Tymnet.COM> Reply-To: jms@tardis.Tymnet.COM (Joe Smith) Organization: BT Tymnet, San Jose, CA Lines: 80 I asked: "How do you scan a directory that may have filenames with embedded blanks". I got help from Francois Rouaix . Many REXX string functions take an optional extra argument to specify the pad character. Sure enough, showdir() takes a 3rd arg. The statement "files=showdir(thisdir)" is the same as "files=showdir(thisdir,'all','20'x)" in that it lists all types of files in the directory thisdir, and separates the names with blanks ('20'x). The only character guaranteed not to be part of any filename is '00'x. /* LISTDIR - List directory and its subdirectories, using relative path names. This AREXX script was created because the 'LIST ALL LFORMAT=' command can be made to output 1) just the filename, or 2) the absolute path name (including volume name), but not 3) path name relative to current directory. */ parse arg topdir opts . if topdir = "" then do parse source . . myname . /* get name of this script */ say 'Usage: rx' myname 'directory-name' say ' To list all files and subdirectories of "directory-name".' say 'Usage: rx >RAM:temp' myname '"" QUICK' say ' To list just the filenames only. "" means current directory.' say ' The options FILES and DIRS also produce a QUICK listing.' exit end quickflag = abbrev("QUICK",upper(opts),1) /* no sizes, dates, etc */ filesonly = abbrev("FILES",upper(opts),1) /* list files only, QUICK */ dirsonly = abbrev("DIRS",upper(opts),1) /* directorys only, QUICK */ call addlib('rexxsupport.library',0,-30,0) /* in case not already added */ if topdir = "''" | topdir = '""' then topdir = "" /* default directory */ if word(statef(topdir),1) ~= "DIR" then say "Error:" topdir "is not a directory" else call scandir topdir /* do recursive directory traversal */ exit scandir: procedure expose quickflag filesonly dirsonly parse arg dir /* variable 'dir' may contain blanks and lowercase letters */ slash = "/" if right(dir,1) = ":" | dir = "" then slash = "" if dirsonly then file = "dir"; else file = "all" files = showdir(dir,file,'00'x) /* list of files, separated by NULL bytes*/ do while words(files) > 0 delimiter = pos('00'x,files) /* locate the NULL */ if delimiter = 0 then delimiter = length(files)+1 /* only one name */ file = dir||slash||substr(files,1,delimiter-1) /* first name */ files = substr(files,delimiter+1) /* all but 1st name */ sf = statef(file) /* note: filename may contain embedded blanks*/ /* statef returns {DIR|FILE} length blocks protect days mins ticks note... */ if sf = "" then say "Cannot locate" file else do if quickflag | filesonly | dirsonly then do if word(sf,1) = "FILE"& ~dirsonly then say file if word(sf,1) = "DIR" & ~filesonly then say file end else do f=left(word(sf,1),4)||right(word(sf,2),8)||right(word(sf,3),5)||dat(sf) say f file if word(sf,8) ~= "" then say ":" subword(sf,8) /* list the filenote */ end if word(sf,1) = "DIR" then call scandir file /* process subdir */ end end return dat: procedure /* returns date/time as " YY/MM/DD HH:MM" */ arg stat /* seconds = word(stat,7)%50 */ minutes = word(stat,6)//60 if minutes < 10 then minutes = "0"||minutes hours = word(stat,6)% 60 if hours < 10 then hours = "0"||hours return ' '||date('O',word(stat,5),I)||' '||hours||':'||minutes /* End of Rexx:ListDir.rexx */ -- Joe Smith (408)922-6220 | SMTP: jms@tardis.tymnet.com or jms@gemini.tymnet.com BT Tymnet Tech Services | UUCP: ...!{ames,pyramid}!oliveb!tymix!tardis!jms PO Box 49019, MS-C51 | BIX: smithjoe | CA license plate: "POPJ P," (PDP-10) San Jose, CA 95161-9019 | humorous dislaimer: "My Amiga 3000 speaks for me."