TOPIC: ZIP
Safe file copying methods for cross platform SAS programming
Not so long ago, I needed to copy a file within a SAS program, only to find that an X command would not accomplish the operation. That cast my mind back to file operations using SAS in order to be platform-independent. Thus, I fell upon statements within a data step.
Before going that far, you need to define filename statements for the source and target locations like this:
filename src "<location of source file or files>" lrecl=32767 encoding="utf-8";
filename dst "<target location for copies>" lrecl=32767 encoding="utf-8";
Above, I also specified logical record length (LRECL) and UTF-8 encoding. The latter is safer in these globalised times, when the ASCII character set does not suffice for everyday needs.
Once you have defined filename statements, you can move to the data step itself, which does not output any data set because of the data _null_ statement:
data _null_;
length rc msg $ 300;
rc = fcopy('src','dst');
if rc ne 0 then do;
msg = sysmsg();
putlog "ERROR: FCOPY failed rc=" rc " " msg;
end;
else putlog "NOTE: Copied OK.";
run;
The main engine here is the fcopy function, which outputs a return code (rc). Other statements like putlog are there to communication outcomes and error messages when the file copying operation fails. The text of the error message (msg) comes from the sysmsg function. After file copying has completed, it is time to unset the filename statements as follows:
filename src clear;
filename dst clear;
One thing that needs to be pointed out here is that this is an approach best reserved for text files like what I was copying when doing this. When I attempted the same kind of operation with an XLSX file, the copy would not open in Excel afterwards. Along the way, it had got scrambled. Once you realise that an XLSX file is essentially a zip archive of XML files, you might see how that could go awry.
Unzipping more than one file at a time in Linux and macOS
To me, it sounded like a task for shell scripting, but I wanted to extract three zip archives in one go. They had come from Google Drive and contained different splits of the files that I needed, raw images from a camera. However, I found a more succinct method than the line of code that you see below (it is intended for the BASH shell):
for z in *.zip; do; unzip "$z"; done
That loops through each file that matches a glob string. All I needed was something like this:
unzip '*.zip'
Without embarking on a search, I got close but have not quoted the search string. Without the quoting, it was not working for me. To be sure that I was extracting more than I needed, I made the wildcard string more specific for my case.
Once the extraction was complete, I moved the files into a Lightroom Classic repository for working on them later. All this happened on an iMac, but the extraction itself should work on any UNIX-based operating system, so long as the shell supports it.