How do I exclude specific file names from an MS DO

2019-05-24 06:41发布

问题:

I am creating an MS DOS batch script that needs to list every .bat file in the current directory, but not show autoexec.bat or other utilities or systems .bat files that shouldn't be run by the user.

I currently have DIR "*.bat" /B /P

This lists all .bat files appropriately, but it shows autoexec.bat. How would I exclude that from the list? Also slightly important, how could I chop off the file extensions and show more than the 7-characters DOS limits files to?

Constraints: I am not able to use a DOS version above WinME. That is the version I am using.

Thanks for any help.

EDIT: There is plenty of information on the internet about doing this, but it is all in the windows command processor, not MS DOS. Please understand that DOS and the Command Prompt are not the same thing.

回答1:

@echo off
setlocal EnableDelayedExpansion
rem Add more names separated with slashes here:
set exclude=/autoexec/
for %%a in (*.bat) do (
   if "!exclude:/%%~Na/=!" equ "%exclude%" (
      echo %%~Na
   )
)

EDIT: Some explanations added

Batch file processing is slow, so you should use techniques that allows a Batch file to run faster. For example:

  • Try to use the minimum lines/commands to achieve a certain result. Try to avoid external commands (*.exe files) like find, findstr, fc, etc. specially if they work on small amounts of data; use if command instead.
  • Use for %%a in (*.bat)... instead of for /F %%a in ('dir /B *.bat').... The second method requires to execute cmd.exe and store its output in a file before for command can process its lines.
  • Avoid pipes and use redirections instead. A pipe require the execution of two copies of cmd.exe to process the command at each side of the pipe.
  • A simple way to check if a variable contain a given string is trying to delete the string from the variable: if the result is different then the string exists in the variable: if "!variable:%string%=!" neq "%variable%" echo The string is in the variable.
  • Previous method may also be used to check if a variable have anyone of a list of values: set list=one two three, if "!list:%variable%=!" neq "%list%" echo The variable have one value from the list. If the values of the list may have spaces, they must be separated by another delimiter.

EDIT: New version added as answer to new comments

The easiest way to pause one page at a time is to use more filter this way:

theBatchFile | more

However, the program must reorder the output in order to show it in columns. The new version below achieve both things, so it does not require more filter; you just need to set the desired number of columns and rows per page.

@echo off
setlocal EnableDelayedExpansion
rem Add more names separated with slashes here:
set exclude=/autoexec/
rem Set the first two next variables as desired:
set /A columns=5, rows=41,   wide=(80-columns)/columns, col=0, row=0
rem Create filling spaces to align columns
set spaces=
for /L %%a in (1,1,%wide%) do set spaces= !spaces!
set line=
for %%a in (*.bat) do (
   if "!exclude:/%%~Na/=!" equ "%exclude%" (
      rem If this column is less than the limit...
      set /A col+=1
      if !col! lss %columns% (
         rem ... add it to current line
         set name=%%~Na%spaces%
         set "line=!line!!name:~0,%wide%! "
      ) else (
         rem ... show current line and reset it
         set name=%%~Na
         echo !line!!name:~0,%wide%!
         set line=
         set /a col=0, row+=1
         rem If this row is equal to the limit...
         if !row! equ %rows% (
            rem ...do a pause and reset row
            pause
            set row=0
         )
      )
   )
)
rem Show last line, if any
if defined line echo %line%

Antonio



回答2:

attrib +h autoexec.bat

should hide autoexec.bat and it should thus not appear in the list



回答3:

DIR "*.bat" /B /P | find /v "autoexec" | for %i in (*.bat) do @echo %~ni


回答4:

Using for to process each file name individually:

setlocal enabledelayedexpansion
for /f %%i in ('dir "*.bat" /b') do (
  set system=0
  if "%%i"=="autoexec.bat" set system=1
  if "%%i"=="somesystem.bat" set system=1
  if !system!==0 echo %%i
)

Another method without variables:

for /f %%i in ('dir "*.bat" /b') do call :test %%i
goto continue
  :test
  if "%1"=="autoexec.bat" goto :eof
  if "%1"=="somesystem.bat" goto :eof
  echo %1
  goto :eof
:continue

For both, you can add new filenames to exclude from the list.