2

我正在创建一个 MS DOS 批处理脚本,它需要列出当前目录中的每个 .bat 文件,但不显示autoexec.bat不应由用户运行的其他实用程序或系统 .bat 文件。

我目前有DIR "*.bat" /B /P

这会适当地列出所有 .bat 文件,但会显示 autoexec.bat。我如何将其从列表中排除?同样重要的是,我怎么能砍掉文件扩展名并显示超过 7 个字符的 DOS 限制文件?

限制:我无法使用 WinME 以上的 DOS 版本。那是我正在使用的版本。

谢谢你的帮助。

编辑: 互联网上有很多关于这样做的信息,但它们都在 Windows 命令处理器中,而不是MS DOS。请理解 DOS 和命令提示符不是一回事。

4

4 回答 4

8
@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
   )
)

编辑添加了一些解释

批处理文件处理速度很慢,因此您应该使用使批处理文件运行得更快的技术。例如:

  • 尝试使用最少的行/命令来达到一定的效果。尽量避免使用外部命令(*.exe 文件),例如findfindstrfc等,尤其是在处理少量数据时;改用if命令。
  • 使用for %%a in (*.bat)...而不是for /F %%a in ('dir /B *.bat').... 第二种方法需要执行 cmd.exe 并将其输出存储在文件中,然后for命令才能处理其行。
  • 避免使用管道并改用重定向。管道需要执行两个 cmd.exe 副本来处理管道每一侧的命令。
  • 检查变量是否包含给定字符串的一种简单方法是尝试从变量中删除字符串:如果结果不同,则字符串存在于变量中:if "!variable:%string%=!" neq "%variable%" echo The string is in the variable
  • 以前的方法也可用于检查变量是否具有值列表中的任何一个:set list=one two three, if "!list:%variable%=!" neq "%list%" echo The variable have one value from the list. 如果列表的值可能包含空格,则它们必须由另一个分隔符分隔。

编辑添加新版本作为对新评论的回答

一次暂停一页的最简单方法是以more这种方式使用过滤器:

theBatchFile | more

但是,程序必须重新排序输出才能在列中显示。下面的新版本实现了这两个东西,所以它不需要more过滤器;您只需要设置每页所需的列数和行数。

@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%

安东尼奥

于 2013-03-30T16:24:21.670 回答
2
attrib +h autoexec.bat

应该隐藏 autoexec.bat,因此它不应该出现在列表中

于 2013-03-30T03:41:11.660 回答
1
DIR "*.bat" /B /P | find /v "autoexec" | for %i in (*.bat) do @echo %~ni
于 2013-03-30T03:11:10.043 回答
0

用于单独for处理每个文件名:

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
)

另一种没有变量的方法:

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

对于这两者,您都可以添加新的文件名以从列表中排除。

于 2013-03-30T06:35:25.927 回答