如何只执行文件夹中名称以两位数字开头的所有 SQL 个文件,而忽略所有其他 SQL 个文件?

How to execute only all SQL files of which name starts with a two digit number in a folder and ignore all other SQL files?

我有以下批处理代码,它执行一个文件夹的所有 SQL 个文件。

for /r %%G in (*.sql) do sqlcmd /S localhost /d superDB /U sa /P topsecret -i"%%G"
pause

但现在我只想执行名称中以两位数字开头的文件,例如:

01_file.sql
02_file.sql
05_file.sql
43_file.sql

但不是这样的文件:

optional_01_file.sql 
XYZ04_file.sql

谁能告诉我如何更改代码以仅过滤文件名以 2 位数字开头的文件?

Findstr 的基本 RegEx 功能足以匹配文件。
Un已测试:

:: Q:\Test18\SO_51456661.cmd
@echo off
for /r %%G in (*.sql) do (
    Echo=%%~nG|Findstr "^[0-9][0-9]_" 2>&1>Nul && (
        echo sqlcmd /S localhost /d superDB /U sa /P topsecret -i"%%G"
    )
)

在包含这些文件的文件夹中

> dir /B *.sql
01_file.sql
0815_file.sql
55_file.sql
abc0855_file.sql

我得到了这些命令(仅回显用于演示)

> SO_51456661.cmd
sqlcmd /S localhost /d superDB /U sa /P topsecret -i"Q:\Test18_file.sql"
sqlcmd /S localhost /d superDB /U sa /P topsecret -i"Q:\Test18_file.sql"

我建议为此任务使用以下批处理文件:

@for /F "delims=" %%G in ('dir "%~dp0??_*.sql" /A-D-H /B /ON 2^>nul ^| %SystemRoot%\System32\findstr.exe /B /R "[0123456789][0123456789]"') do @sqlcmd.exe /S localhost /d superDB /U sa /P topsecret -i"%~dp0%%G"

此批处理文件要求以[0-9][0-9]_开头的*.sql文件与批处理文件存储在同一目录下,运行批处理文件的当前目录可以是运行 此批处理文件作为计划任务有用的任何目录,其中未设置计划任务的 开始时间 选项。

要处理当前目录中的 *.sql 文件而不是批处理文件的目录,只需删除两个出现的 %~dp0 即可扩展到批处理文件的驱动器和路径。扩展的批处理文件路径字符串始终以反斜杠结尾。

两者 %~dp0 也可以替换为任何其他以反斜线结尾的文件夹路径。

带有所用选项的命令 FOR 在单独的命令进程中运行,在后台命令行 cmd /C 中启动

dir "C:\Batch File Path\??_*.sql" /A-D-H /B /ON 2>nul | C:\Windows\System32\findstr.exe /B /R /C:[0123456789][0123456789]

命令DIR搜索

  • 只是非隐藏文件,因为 /A-D-H(属性不是目录,也不是隐藏的)
  • 在批处理文件的目录中
  • 对于匹配通配符模式的文件 ??_*.sql
  • 并且只输出文件名+文件扩展名来处理STDOUT(标准输出)因为/B(裸格式)
  • 由于 /ON.
  • 按名称字母顺序排列

DIRcmd.exe 的内部命令,已经 运行 用于处理这个批处理文件。

DIR 输出的错误消息,关于找不到任何符合写入处理 STDERR(标准错误)的标准的文件名被重定向使用 2>nul 到设备 NUL 来抑制它。

DIR 处理 STDOUT 的输出被重定向 | 处理 STDIN(标准输入)下一个命令 FINDSTR 是一个外部命令,这意味着控制台可执行文件在 Windows 系统目录中默认可用。

FINDSTR 搜索从 STDIN which

读取的行
  • 开始是因为 /B
  • 与字符串匹配 [0123456789][0123456789]
  • 因为显式使用 /R.
  • 被解释为正则表达式搜索字符串

使用[0123456789][0123456789]而不是[0-9][0-9]的原因见What are the undocumented features and limitations of the Windows FINDSTR command?,因为[0-9]也匹配用代码页编码的三个字符¹²³ Windows-1252.

FINDSTR 输出匹配正则表达式的所有行(=文件名)仅应用于前两个字符以处理背景的 STDOUT命令进程。

FOR 捕获这些文件名并逐行处理它们。 delims= 定义了一个用于字符串拆分的空列表,即使 *.sql 文件名包含一个或多个空格,也始终将文件的全名分配给循环变量 G

另请阅读有关 Using Command Redirection Operators 的 Microsoft 文章,了解 |2>nul 的解释。重定向运算符 >| 必须在 FOR 命令行上使用脱字符 ^ 进行转义,以便在 [=175= 时将其解释为文字字符] 命令解释器在执行命令 FOR 之前处理此命令行,该命令在后台启动的单独命令进程中执行带有 findstr 的嵌入式 dir 命令行。

最好在 运行 这个批处理文件上同时指定 sqlcmd.exe 和完整路径作为计划任务,以使批处理文件独立于环境的环境变量 PATH(帐户) 用于 运行 计划任务。

有点不清楚是*.sql文件夹中以两位数字和下划线开头的文件还是递归文件夹及其所有子文件夹中的文件应该以sqlcmd执行。

这是上述批处理文件命令行的一个变体,用于 运行 所有 *.sql 在整个文件夹树中以 [0-9][0-9]_ 开头,从包含批处理文件的文件夹开始:

@for /F "delims=" %%G in ('dir "%~dp0??_*.sql" /A-D-H /B /ON /S 2^>nul ^| %SystemRoot%\System32\findstr.exe /R /C:"\[0123456789][0123456789]_[^\]*$"') do @sqlcmd.exe /S localhost /d superDB /U sa /P topsecret -i"%%G"

命令 DIR 还与选项 /S 一起使用,这导致还在子目录中搜索与通配符模式 ??_*.sql.[=57 匹配的文件=]

DIR 的输出随着 /S 的变化而变化,因为文件名现在以完整的文件路径输出。

因此 FINDSTR 没有 /B 并且正则表达式被修改为 \[0123456789][0123456789]_[^\]*$ 以仅输出 *.sql文件名中以两位数字开头的文件与文件路径无关。

命令 sqlcmd 仅通过 %%G 调用,因为循环变量包含当前 SQL 的完整限定文件名(=文件路径 + 文件名 + 文件扩展名)要使用的文件。

要了解使用的命令及其工作原理,请打开命令提示符 window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • dir /?
  • findstr /?
  • for /?
  • sqlcmd -?

我会使用 findstr 按名称过滤文件,如下所示:

for /F "delims=" %%G in ('
    dir /S /B /A:-D "*.sql" ^| ^
        findstr /I /R /C:"\[0123456789][0123456789]_[^\]*\.sql$"
') do (
    sqlcmd /S localhost /d superDB /U sa /P topsecret -i"%%G"
)
pause