85} How to test if a folder contains any files with long names?
What is a long file name (LFN)? To a degree a misnomer. Best defined
as a complement of the old MS-DOS file name, that is the familiar
max 8+3 and no spaces.
Two main testing possibilities arise. Using the said complement
definition. Or using the fact that in Microsoft's usage the long and
the short file name (SFN) will differ.
The solutions below are based on the format of DIR /X /A:-D listing.
(The /A:-D means that the subfolders and thier names are not to be
tested.) E.g. one might have
C:\_M>DIR /X /A:-D
Volume in drive C is WHATEVER
Volume Serial Number is 61C1-66A2
Directory of C:\_M
13.06.2008 16:19 496 CMDFAQ.CMD
13.06.2008 16:20 18 LONGNA~1.TXT LongNameFile.txt
13.06.2008 16:21 13 TEST2~1.CMD test 2.cmd
13.06.2008 16:21 11 test.cmd
4 File(s) 538 bytes
0 Dir(s) 230,906,830,848 bytes free
The first solution option is based on the fact that if DIR /X is used
to get a folder listing the results will differ from the plain DIR
listing if there are long file names. Else, no difference, but in the
spacing.
@echo off & setlocal enableextensions
set dir1_=c:\_m\dirtmp1.txt
set dirx_=c:\_m\dirtmpx.txt
::
if "%~1"=="" (echo Usage [FolderName]&goto :EOF)
::
dir "%~1" /a:-d /-c > "%dir1_%
dir "%~1" /x /a:-d /-c > "%dirx_%
::
fc
/w "%dir1_%" "%dirx_%" > nul
if %errorlevel% EQU 0 (
echo No long file names found in "%~1"
) else (
echo Long file names found in "%~1")
::
for %%f in ("%dir1_%" "%dirx%") do if exist %%f del %%f
endlocal & goto :EOF
The output could be e.g.
C:\_M>cmdfaq C:\_M
Long file names found in "C:\_M"
The second option is based on the following fact. For a long file name
the relevant row contains at least five space delimited items while
the other lines only have four. Furthermore, the folder listing's
footer must be dropped.
@echo off & setlocal enableextensions
set lfn_=
for /f "skip=4 tokens=4-5 delims= " %%a in (
'dir /x /a:-d /-c "%~1" ^|findstr /v /b /c:" "') do (
if not [%%b]==[] if /i not [%%a]==[%%b] set lfn_=true)
if [%lfn_%]==[] (
echo No long file names found in folder %1
) else (
echo Long file names found in folder %1)
endlocal & goto :EOF
For more information you may wish to take a look at
dir /?
findstr /?|more
There are other methods. First consider the task of getting the
short format of a single filename
@echo off & setlocal enableextensions enabledelayedexpansion
for %%f in ("%~1") do (
set lfn=%%~ff
set sfn=%%~sf
if not exist "!lfn!" (
echo File "!lfn!" not found
) else (
echo !lfn!
echo !sfn!
)
)
endlocal & goto :EOF
The output might be e.g.
C:\_D\TEST>cmdfaq "C:\_M\test 2.txt"
C:\_M\test 2.txt
C:\_M\TEST2~1.TXT
Note, however, that this method will fail if there are exclamation
marks (!) in the file name.
Drawing from the above we could have
@echo off & setlocal enableextensions enabledelayedexpansion
::
if "%~1"=="" (
echo Usage %~0 [FolderName]
goto :EOF
)
::
if not exist "%~1\" (
echo Folder "%~1\" not found
goto :EOF
)
::
set lfnFound=
for %%f in ("%~1\*.*") do (
set lfn=%%~ff
set sfn=%%~sf
if /i not "!lfn!"=="!sfn!" set lfnFound=true
)
::
if defined lfnFound (
echo Long file names found in folder "%~1"
) else (
echo No long file names found in folder "%~1")
endlocal & goto :EOF
The output might be e.g.
C:\_D\TEST>cmdfaq C:\_D\TEST
Long file names found in folder "C:\_D\TEST"
Of course one could start from the definition of the long file name,
but this solution does not tolerate the poison charaters.
@echo off & setlocal enableextensions
set lfn_=
set base_=%~n1
set exte_=%~x1
if not "%base_:~8%"=="" set lfn_=true
if not "%exte_:~4%"=="" set lfn_=true
echo %~nx1|find " ">nul
if %errorlevel% EQU 0 set lfn_=true
echo "%~1"
if defined lfn_ echo is a long file name
if not defined lfn_ echo is not a long file name
endlocal & goto :EOF