BookmarkSubscribeRSS Feed
RichardAD
Quartz | Level 8

I am dealing with some files that need to be FDELETED after they are used.  However, I only get a log message:

ERROR: Invalid physical name.

 

I've discovered I can used brackets in some scenarios by using backslash (\[)...\]) to apparently escape the [ which causes the above error.

I recall reading some SAS documentation that [] in filename is used like a regex character class, but I can't find that doc again -- it might have been Viya related, but I am not using Viya.

 

Example:

%let workpath = %sysfunc(pathname(WORK)) ;
%let testpath = &workpath/test ;

options dlcreatedir ;
libname testpath "&testpath" ;
options nodlcreatedir ;

* Create a test file whose name contains brackets ;
filename bracket "&testpath/ABC_\[123\]_DEF.txt" ; ata _null_; file bracket; put 'Where do you want these shelves?'; run ;
* Process the test file ;
data _null_ ; infile bracket ; input; put _infile_; run; * List the files in test folder and try to delete them with FDELETE ; data _null_ ; length dref fref $8 fname $256 msg $200 ; rc = filename (dref, "&testpath") ; did = dopen(dref); msg=sysmsg() ; do i = 1 to dnum(did) ; fname = dread(did, i) ; put 'NOTE: ' i fname ; rc = filename (fref, cats("&testpath",'/',fname)) ; msg = sysmsg() ; put 'NOTE: filename() ' rc= fname= / msg ; rc = FDELETE(fref) ; msg = sysmsg() ; put 'NOTE: fdelete() ' rc= / msg ; if index(fname,'[') then do ; fname = transtrn(fname,'[','\[') ; * try to escape the brackets ; fname = transtrn(fname,']','\]') ; rc = filename (fref, cats("&testpath",'/',fname)) ; msg = sysmsg() ; put 'NOTE: filename() ' rc= fname= / msg ; rc = FDELETE(fref) ; msg = sysmsg() ; put 'NOTE: fdelete() ' rc= / msg ; end ; rc = filename (fref) ; end ; run ; * try delete the escaped filename referenced by bracket; %put NOTE: FDELETE rc=%sysfunc(fdelete(bracket)) ; %put %sysfunc(sysmsg()) ;

will log the ERROR: for each way I try to FDELETE

225        %let workpath = %sysfunc(pathname(WORK)) ;
226        %let testpath = &workpath/test ;
227        
228        options dlcreatedir ;
229        libname testpath "&testpath" ;
NOTE: Libref TESTPATH was successfully assigned as follows: 
      Engine:        V9 
      Physical Name: /saswork/sas_tmp/SAS_work##########/SAS_work##########/test
230        options nodlcreatedir ;
231        
232        filename bracket "&testpath/ABC_\[123\]_DEF.txt" ;
233        
234        data _null_;
235          file bracket;
236          put 'Where do you want these shelves?';
237        run ;

NOTE: The file BRACKET is:
      Filename=/saswork/sas_tmp/SAS_work##########/SAS_work##########/test/ABC_\[123\]_DEF.txt,
      Owner Name=########,Group Name=########,
      Access Permission=-rw-rw-rw-,
      Last Modified=17Jul2025:08:27:44

NOTE: 1 record was written to the file BRACKET.
      The minimum record length was 32.
      The maximum record length was 32.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

238        
239        data _null_ ;
240          infile bracket ;
241          input; put _infile_;
242        run;

NOTE: The infile BRACKET is:
      Filename=/saswork/sas_tmp/SAS_work##########/SAS_work##########/test/ABC_\[123\]_DEF.txt,
      Owner Name=########,Group Name=########,
      Access Permission=-rw-rw-rw-,
      Last Modified=17Jul2025:08:27:44,
      File Size (bytes)=33

Where do you want these shelves?
NOTE: 1 record was read from the infile BRACKET.
      The minimum record length was 32.
      The maximum record length was 32.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

243        
244        * List the files in test folder and try to delete them ;
245        
246        data _null_ ;
247         length dref fref $8 fname $256 msg $200 ;
248          rc = filename (dref, "&testpath") ;
249          did = dopen(dref);  msg=sysmsg() ;
250          do i = 1 to dnum(did) ;
251            fname = dread(did, i) ;
252            put 'NOTE: ' i fname ;
253            rc = filename (fref, cats("&testpath",'/',fname)) ; msg = sysmsg() ; put 'NOTE: filename() ' rc= fname= / msg ;
254            rc = FDELETE(fref) ;  msg = sysmsg() ; put 'NOTE: fdelete() ' rc= / msg ;
255            if index(fname,'[') then do ;
256              fname = transtrn(fname,'[','\[') ;
257              fname = transtrn(fname,']','\]') ;
258              rc = filename (fref, cats("&testpath",'/',fname)) ; msg = sysmsg() ; put 'NOTE: filename() ' rc= fname= / msg ;
259              rc = FDELETE(fref) ;  msg = sysmsg() ; put 'NOTE: fdelete() ' rc= / msg ;
260            end ;
261            rc = filename (fref) ;
262          end ;
263        run ;

NOTE: 1 ABC_[123]_DEF.txt
NOTE: filename() rc=0 fname=ABC_[123]_DEF.txt

NOTE: fdelete() rc=20017
ERROR: Invalid physical name.
NOTE: filename() rc=0 fname=ABC_\[123\]_DEF.txt

NOTE: fdelete() rc=20017
ERROR: Invalid physical name.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds
      

264        
265        * try delete the escaped filename referenced by bracket;
266        
267        %put NOTE: macro FDELETE rc=%sysfunc(fdelete(bracket)) ;
NOTE: macro FDELETE rc=20017
268        %put %sysfunc(sysmsg()) ;
ERROR: Invalid physical name.
3 REPLIES 3
Tom
Super User Tom
Super User

I would raise that as an issue with SAS support.

 

Square brackets should not cause any trouble in SAS code and I am pretty sure they did not in the past.  But at the very least FDELETE() should handle the same way as normal writing and reading operations do.

 

I have definitely had the opposite problem in the past.  SAS would allow you to make filenames that are difficult to work with from Unix prompt.  Names with spaces or * in them.

 

Tom
Super User Tom
Super User

If you do have XCMD option enabled you can use the Unix command rm to delete the file.

data _null_;
  cmd=catx(' ','rm',pathname('bracket'));
  infile dummy pipe filevar=cmd;
  input;
  put _infile_;
run;

 

PS  You might need use \rm instead of rm as the command.  This will force it use the rm command directly instead of any alias that might have been defined.  to avoid complication from Unix shops that have defined aliases for rm to force it to prompt before removing a file. 

yabwon
Amethyst | Level 16

Hi @RichardAD 

 

I won't help you with a solution, unfortunately, but I have some more observations.

1) It looks like it it's not only FDELETE() have problems with [].

My idea was "let's try rename and the delete", so I did a small test for RENAME() with 6 different approaches, but it returned the same error, log below.

 1          %put %sysfunc(rename(&testpath./ABC_\[123\]_DEF.txt, &testpath./ABC_123_DEF.txt, file));
 1
 2          %put %sysfunc(sysmsg()) ;
 ERROR: Invalid physical name.
 3          
 4          %put %sysfunc(rename("&testpath./ABC_[123]_DEF.txt", &testpath./ABC_123_DEF.txt, file));
 1
 5          %put %sysfunc(sysmsg()) ;
 ERROR: Invalid physical name.
 6          
 7          %put %sysfunc(rename('&testpath./ABC_[123]_DEF.txt', &testpath./ABC_123_DEF.txt, file));
 1
 8          %put %sysfunc(sysmsg()) ;
 ERROR: Invalid physical name.
 9          
 10         %put %sysfunc(rename(%str(&testpath./ABC_\[123\]_DEF.txt), &testpath./ABC_123_DEF.txt, file));
 1
 11         %put %sysfunc(sysmsg()) ;
 ERROR: Invalid physical name.
 12         
 13         %put %sysfunc(rename("&testpath./ABC_\[123\]_DEF.txt", &testpath./ABC_123_DEF.txt, file));
 1
 14         %put %sysfunc(sysmsg()) ;
 ERROR: Invalid physical name.
 15         
 16         %put %sysfunc(rename('&testpath./ABC_\[123\]_DEF.txt', &testpath./ABC_123_DEF.txt, file));
 1
 17         %put %sysfunc(sysmsg()) ;
 ERROR: Invalid physical name.

 

2) Furthermore, when I tried delete "ABC_[123]_DEF.txt" in SAS Studio I also got an error.

 

3) Another "fun fact" is that when I created a directory with [], Linux tree command on OS level shows:

 

.
├── ABC_[123]_DEF.txt
├── DEF_[123]_DEF.txt
├── GHI_[123]_DEF.txt
└── test[123]
    ├── test[123]next.txt
    └── test.txt

1 directory, 5 files

but SAS Studio does not see that sub-directory at all:

 

 

yabwon_0-1752760884343.png

Last 2 things. If you happen to have XCMD on, maybe you could use filename PIPE to run;

rm '/path/to/file/ABC_[123]_DEF.txt';

on the OS level, with filename surrounded by quotes.

Or, in the BasePlus package there is the %bpPIPE() macro that may be useful:

%bpPIPE(rm "&testpath./ABC_[123]_DEF.txt")

 

All the best

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

Register Now

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 3 replies
  • 505 views
  • 0 likes
  • 3 in conversation