This page is edited from the 1cmdfaq.txt faq-file contained in
my tscmd.zip
command line interface (CLI) collection. That zipped file has much
additional material, including a number of detached .cmd script
files. It is recommended that you also get the zipped version as a
companion.
Please see "
The Description and
the Index page" for the conditions of usage and other such
information.
186} How to list folders which have files with % ! & or ^ in the names?
Assume that we wish to check a folder and its subfolders C:\_M
@echo off & setlocal enableextensions disabledelayedexpansion
for /f "delims=" %%a in ('dir "C:\_M\" /a:d /b /s') do (
pushd "%%a"
dir /b "*%%*" "*!*" "*&*" "*^*" >nul 2>&1 && echo %%a
popd)
endlocal & goto :EOF
- The disabledelayedexpansion is
needed, since else error situations can arise.
- A % needs to be escaped
with another %.
- The >nul 2>&1
suppresses potential script error messages
(cf. Item #9).
This is needed
since it is highly likely that some or many folders will not contain
items with % ! & or ^ in the names.
- The && is to run the command following && only
if the command preceding the symbol is successful.
The task is more complicated than it first appears. What does
one mean by "name". Is it the full name with path, which we wish to
check, or the just file name only. Above, the former was assumed. Thus
given folders like
C:\_M\one & two\
C:\_M\one & two\cache\
C:\_M\one & two\cache\abc\
C:\_M\one & two\cache\def\
not just the folder
C:\_M will be
flagged (as it should), but always also
C:\_M\one & two.
If one wishes to ignore the folder names, that is consider only actual
file names within the folders, just a slight variation is needed
@echo off & setlocal enableextensions disabledelayedexpansion
for /f "delims=" %%a in ('dir "C:\_M\" /a:d /b /s') do (
pushd "%%a"
dir /b /a:-d "*%%*" "*!*" "*&*" "*^*" >nul 2>&1 && echo %%a
popd)
endlocal & goto :EOF
However, it does not quite end here yet, since the above solutions
ignore the starting folder. Hence
@echo off & setlocal enableextensions disabledelayedexpansion
set top_=C:\_M
dir /b /a:-d "%top_%\*%%*" "%top_%\*!*" "%top_%\*&*" "%top_%\*^*" >nul 2>&1 && echo %top_%
for /f "delims=" %%a in ('dir "%top_%\" /a:d /b /s') do (
pushd "%%a"
dir /b /a:-d "*%%*" "*!*" "*&*" "*^*" >nul 2>&1 && echo %%a
popd)
endlocal & goto :EOF
How about listing
files with
%!& or
^
in the full names? A different, FINDSTR approach:
@echo off & setlocal enableextensions disabledelayedexpansion
set filelist_=%mytemp%\filelist.tmp
set top_=C:\_M
dir /s /b "%top_%\" > "%filelist_%
findstr /c:"%%" /c:"!" /c:"&" /c:"^" "%filelist_%"
for %%f in ("%filelist_%") do if exist %%f del %%f
endlocal & goto :EOF
What if you wish to flag only if the special character is the
file name, but ignore them in the path.
@echo off & setlocal enableextensions disabledelayedexpansion
set filelist1_=%mytemp%\filelist1.tmp
set filelist2_=%mytemp%\filelist2.tmp
set top_=C:\_M
dir /s /b "%top_%\" > "%filelist1_%
findstr /c:"%%" /c:"!" /c:"&" /c:"^" "%filelist1_%" > "%filelist2_%"
for /f "tokens=* delims=" %%f in ('type "%filelist2_%"') do (
if not exist "%%~f\" echo %%~dpf %%~nxf )
for %%f in ("%filelist1_%" "%filelist2_%") do if exist %%f del %%f
endlocal & goto :EOF
Note the usage of the temporary files instead of using pipes. This is
because with a potentially huge number of files a pipe would choke.