如何仅执行文件夹中名称以两位数开头的所有 SQL 文件,并忽略所有其他 SQL 文件



我有以下批处理代码,可以执行文件夹的所有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的基本正则表达式功能足以匹配文件。
未经测试:

:: Q:Test2018721SO_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:Test20187211_file.sql"
sqlcmd /S localhost /d superDB /U sa /P topsecret -i"Q:Test201872155_file.sql"

我会使用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

我建议为此任务提供以下批处理文件:

@for /F "delims=" %%G in ('dir "%~dp0??_*.sql" /A-D-H /B /ON 2^>nul ^| %SystemRoot%System32findstr.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:WindowsSystem32findstr.exe /B /R /C:[0123456789][0123456789]

命令DIR搜索

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

DIR是已运行的用于处理此批处理文件的cmd.exe的内部命令。

如果找不到与处理STDRR(标准错误)而编写的条件匹配的任何文件名,DIR输出的错误消息将2>nul重定向到设备NUL以禁止显示它。

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

FINDSTR搜索从STDIN读取的行,其中

  • 开始是因为/B
  • 与字符串匹配[0123456789][0123456789]
  • 由于使用显式/R,因此被解释为正则表达式搜索字符串。

请参阅 Windows FINDSTR 命令的未记录功能和限制是什么?原因使用[0123456789][0123456789]而不是[0-9][0-9]因为[0-9]也匹配使用代码页 Windows-1252 编码时¹²³的三个字符。

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

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

另请阅读有关使用命令重定向运算符的Microsoft文章,了解|2>nul的说明。重定向运算符>|必须在 FOR 命令行上使用插入符号^进行转义,以便在 Windows 命令解释器在执行命令 FOR 之前处理此命令行时将其解释为文字字符,该命令FOR使用在后台启动的单独命令进程执行嵌入式dirfindstr命令行。

最好是指定sqlcmd.exe在将此批处理文件作为计划任务运行时具有完整路径,以使批处理文件独立于用于运行计划任务的环境(帐户)的环境变量PATH

有点不清楚文件夹中是否应该使用sqlcmd执行仅以两位数和下划线开头的 *.sql 文件,还是在文件夹中递归执行。

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

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

命令DIR还与选项/S一起使用,该选项还可以在子目录中搜索与通配符模式??_*.sql匹配的文件。

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

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

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

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

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

最新更新