get short file name when LFN name has two extensions

193 Views Asked by At

I am having an issue getting short file name (SFN) in a batch script to be passed to an old program that only takes 8.3 short file names as command line arguments. I did some testing at cmd.exe prompt here is output to find what was causing problem:

> dir /x *.vi
 Volume in drive C is DSK_C
 Volume Serial Number is FC79-4140

 Directory of c:\Documents and Settings

08/04/2016  10:48               211 Z12TXT~1.VI  z12.TXT.vi
08/04/2016  10:48               211 Z123TX~1.VI  z123.TXT.vi
               2 File(s)            422 bytes
               0 Dir(s)   3,599,233,024 bytes free

> for /F "usebackq tokens=* delims=&" %A in (`echo "c:\Documents and Settings\z1
23.TXT.vi"`) do @echo "result=%~sfA"
"result=c:\DOCUME~1\Z123TX~1.VI"

> for /F "usebackq tokens=* delims=&" %A in (`echo "c:\Documents and Settings\z1
2.TXT.vi"`) do @echo "result=%~sfA"
"result=c:\DOCUME~1\Z12TXT~1.VIgs\z12.TXT.vi"

In the last command output result=c:\DOCUME~1\Z12TXT~1.VIgs\z12.TXT.vi should be result=c:\DOCUME~1\Z12TX~1.VI. I tried various combinations like adding delims but can't find a solution other than scraping dir output into a var. It looks like if filename is less than or equal to 7 characters (%~nA part) and contains a period then %~sfA or %~snxA has incorrect result. Is that right and are there any other simpler solutions?

Edit Apr 12: Just to clarify path is not a problem but in the above example %~sfA path is corrupt but %~sdpA would be c:\DOCUME~1\Z12TXT~1.VI\

1

There are 1 best solutions below

0
Magoo On
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET "parent=%sourcedir%\"
CALL :resolvedir
for /F "tokens=4delims= " %%A in ('
dir /x /a-d "%sourcedir%\*.vi"^|FINDstr /e /i /L ".vi"
') do echo "result=%parent%%resultd%%%A"


GOTO :EOF

:resolvedir
SET "resultd="
:rdloop
FOR %%J IN ("%parent:~0,-1%") DO (
 FOR /f "tokens=1*delims=\" %%G IN ("%parent%") DO IF "%%H"=="" (
  GOTO :eof
 ) ELSE (
  FOR /F "tokens=1*delims=>" %%A IN ('dir /ad /x "%parent%\.."') DO (
   IF "%%B" neq "" FOR /f "tokens=1*delims= " %%D IN ("%%B") DO (
    IF /i "%%D"=="%%~nxJ" SET "resultd=%%D\%resultd%"&SET "parent=%%~dpJ"
    IF /i "%%E"=="%%~nxJ" SET "resultd=%%D\%resultd%"&SET "parent=%%~dpJ"
   )
  )
 )
)

GOTO rdloop

You would need to change the setting of sourcedir to suit your circumstances.

I'm assuming the source directory is a full pathname including drive letter. No doubt this will show sensitivity to certain characters like the usual suspects, but keep the names to long-pure-alphameric-and spaces-and nice-characters and all should be well.


If there is no need to resolve the directoryname as short, then the above simplifies to

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
for /F "tokens=4delims= " %%A in ('
dir /x /a-d "%sourcedir%\*.vi"^|FINDstr /e /i /L ".vi"
') do echo "result=%%A"

Where the setting and use of of sourcedir is merely for testing purposes.