- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
You can always use a pipe to send and retrieve the results of a dir/x command.
Art
-----------
> Does anyone have a macro utility or procedure that
> can convert the longform windows file names to the
> short form dos version? For example, the path
> c:\program files becomes something like c:\progra~1.
> Also this takes place at the file name level as well
> where "one two three four.xlsx" ends up something
> like onetwo~1.xls.
>
> Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
[pre]
%let Path = .\nPercenOfManyVars.sas;
%let Path = ..;
data ShortName(keep=Path Long: Short: Type);
attrib Path length=$256;
attrib Type length=$8;
attrib LongPathName length=$256;
attrib ShortPathName length=$256;
attrib LongFileName length=$256;
attrib ShortFileName length=$256;
length script filevar command $256;
Path = symget('Path');
script = catx('\',pathname('WORK'),'SHORTPATH.vbs');
filevar = script;
/* Write the script */
file dummy1 filevar=script;
put Path=$quote258.;
infile cards eof=eof;
do while(1);
input;
put _infile_;
end;
eof:
/* close the script file by opening another, not used */
filevar = catx('\',pathname('WORK'),'DUMMY.vbs');
file dummy1 filevar=filevar;
/* look at the script useful for debuging, errors referenced by (row,column) as (13, 7)*/
infile dummy2 filevar=script end=eof;
file log ls=256;
put 'NOTE: ' Script=;
put 'RULE: ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0';
do _n_ = 1 by 1 while(not eof);
input;
putlog 'NOTE-' _n_ z4. @11 _infile_;
end;
/* call the script */
command = catx(' ','cscript //nologo',quote(strip(script)));
infile dummy3 pipe filevar=command end=eof length=l lrecl=512;
put 'NOTE: Data lines returned from: ' command=;
put 'RULE: ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0';
do _n_ = 1 by 1 while(not eof);
input (_all_)(=);
putlog 'NOTE-' _n_ z4. @11 _infile_;
end;
_error_ = 0;
output;
stop;
cards4;
On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Echo "Path=" & path
set f = fso.GetFile(Path)
if err.number <> 0 then
err.number = 0
set f = fso.Getfolder(Path)
if err.number <> 0 then
WSCript.Echo "LongPathName=
else
t = "Folder"
s = f.ShortPath
WScript.Echo "LongPathName=" & f
WScript.Echo "ShortPathName=" & s
Wscript.Echo "Type=" & t
end if
else
s = f.ShortPath
sn = f.ShortName
n = f.Name
t = "File"
WSCript.Echo "LongPathName=" &f
WSCript.Echo "ShortPathName=" &s
WSCript.Echo "LongFileName=" &n
WSCript.Echo "ShortFileName=" &sn
Wscript.Echo "Type=" & t
end if
;;;;
run;
proc print;
run;
proc transpose out=ShortNames;
var _all_;
run;
proc print;
run;
[/pre]
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
You can ask windows kernel via modulen. Packaging it neatly into a user-written function (or a macro) is left as an exercise for the interested reader(s). 🙂
/* cd to work */
%let pwd = %sysfunc(pathname(work));
%put pwd=&pwd;
x cd &pwd;
/* create a test file with a long name */
%let long = long file name.txt;
options noxwait;
x "copy nul ""&long""";
/* create sascbtbl */
filename sascbtbl catalog "work.winapi.fm.source";
data _null_;
file sascbtbl; input; put _infile_;
cards4;
routine GetShortPathNameA module=KERNEL32 minarg=3 maxarg=3 stackpop=called returns=long;
arg 1 input char format=$cstr256.;
arg 2 output char format=$cstr256.;
arg 3 input num format=pib4.;
;;;;
run;
/* call the win32 api func via modulen */
data _null_;
length long short $256;
long = "&long" || byte(0);
short = byte(0);
rc = modulen("*e", "GetShortPathNameA", long, short, 0);
short = scan(short, 1, byte(0));
if rc=0 then
put "Uh-oh!";
else
put (long short) (= :quote.);
run;
filename sascbtbl clear;
/* on log
long="long file name.txt " short="LONGFI~1.TXT"
*/
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Assuming all the files are in c:\temp directory.
[pre]
filename fname pipe 'dir c:\temp\*.* /b';
data _null_;
file 'c:\rename.bat';
infile fname length=len;
input name $varying100. len;
if (length(scan(name,1,'.')) gt 😎 then do;
if findc(strip(name),' ') then do;
rename='rename '||strip(scan(name,1,' .'))||'*.'||strip(scan(name,-1,'.'))||
' '||strip(substr(compress(name),1,6))||'~1.'||strip(scan(name,-1,'.'));
put rename;
end;
else if findc(strip(name),'.') then do;
rename='rename '||strip(name)||' '||
strip(substr(compress(name),1,6))||'~1.'||strip(scan(name,-1,'.'));
put rename;
end;
else do;
rename='rename '||strip(name)||' '||strip(substr(compress(name),1,6))||'~1';
put rename;
end;
end;
run;
x "cd c:\temp\";
x "c:\rename.bat";
x "del c:\rename.bat";
run;
[/pre]
Ksharp