按批量文件名前缀的顺序读取目录中的文件?

时间:2013-09-11 18:35:01

标签: windows batch-file

我在目录中有许多SQL脚本,前缀是数字,例如

enter image description here

目前,我可以使用此脚本循环访问它们:

@ECHO OFF
FOR /r . %%F IN (*.sql) DO (
    ECHO File:"%%F"
)

但是,由于Windows读取目录中文件的方式,在2之前读取10和11,等等:

enter image description here

如何循环浏览目录中的每个文件,按前缀的顺序?

7 个答案:

答案 0 :(得分:7)

下面的批处理文件在需要它的文件名中插入前导零。

@echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%f in ('dir /B *.sql') do (
   set "filename=%%f"
   if "!filename:~1,1!" equ "-" ren "%%f" "0%%f"
)

编辑 :添加了新解决方案

下面的批处理文件以正确的顺序显示文件而不重命名。

@echo off
setlocal EnableDelayedExpansion
rem Create an array with filenames in right order
for %%f in (*.sql) do (
   for /F "delims=-" %%n in ("%%f") do (
      set "number=00000%%n"
      set "file[!number:~-6!]=%%f"
   )
)
rem Process the filenames in right order
for /F "tokens=2 delims==" %%f in ('set file[') do (
   echo %%f
)

答案 1 :(得分:4)

替代方法!

这不是您问题的直接答案,但可能会达到同样的结果:

FOR /L %%i IN (1,1,11) DO FOR %%f IN (%%i-*.sql) DO ECHO %%f

答案 2 :(得分:2)

据我所知,没有FOR标志。

但这里是pure PowerShell solution使用某种奇怪的正则表达式。

或者您可以列出文件,sort,将这些已排序的路径按正确顺序放入文件然后阅读。

第3种解决方案是尝试使用标准的Windows Shell命令和运算符构建一些排序功能。

答案 3 :(得分:2)

编辑 - 使用JSORT.BAT的新简单解决方案

本机批处理SORT命令非常有限。我编写了一个方便的JSORT.BAT sorting utility,它提供了许多方便的功能,包括根据数值对数字字符串进行排序的功能。 JSORT.BAT是纯脚本(混合JScript /批处理),可以在任何Windows机器上本机运行,无需任何第三方exe文件。

您可以使用

以数字方式列出文件
dir /b /a-d *.sql^|jsort /n /i

如果要迭代结果,只需将命令放在FOR / F循环中

for /f "delims=" %%F in ('dir /b /a-d *.sql^|jsort /n /i') do echo %%F

可以使用jsort /?从命令行获取完整文档。


早于JSORT.BAT的原始解决方案

可以在不修改文件名的情况下使用批处理执行所需的操作,如果使用执行正则表达式搜索的hybrid JScript/batch utility called REPL.BAT并在stdin上替换并将结果写入stdout,则效率非常高。该实用程序是从XP开始在任何Windows机器上运行的纯脚本 - 不需要第三方可执行文件。完整的文档嵌入在脚本中。

假设REPL.BAT位于当前目录中,或者更好,位于PATH中的某个位置,则以下内容将迭代以所需排序顺序的数字开头的.sql个文件。如上所述,它支持最多5位数的数字。它可以很容易地扩展到支持更大的数字。

@echo off
for /f "tokens=2 delims=:" %%F in (
  'dir /b /a-d *.sql^|repl "^(\d+).*" "00000$1:$&" a^|repl ".*(\d{5}:)" "$1"^|sort'
) do echo %%F

这确实显示了管道的力量:)。

复杂的IN()子句的工作原理如下:

  1. 列出所有.sql文件
  2. 查找以数字开头的文件,并将每个匹配的名称替换为带有前缀为五个前导零的前导数字,后跟一个冒号,后跟原始名称
  3. 替换前导号码,仅保留最后5位数字
  4. 对结果进行排序
  5. 父FOR / F然后读取结果,将原始文件名解析为第二个:分隔标记。

答案 4 :(得分:1)

根据需要使用前导0重命名脚本,以便前缀中的数字始终具有相同的位数。

答案 5 :(得分:1)

Take Command Console是一个具有免费版本的命令解释器,并且会进行自然排序。

答案 6 :(得分:0)

在批处理中使用powershell进行排序的示例:

FOR /f "usebackq" %%F IN (
  `powershell "ls -r *.sql | sort { [int]($_.Name -replace '\D','') } | %% { $_.FullName }"`
) DO (
    ECHO File:"%%F"
)
  • ls -r *.sqlGet-ChildItem -Recurse的缩写)对应于FOR /r . %%F IN (*.sql)部分
  • sort { [int]($_.Name -replace '\D','') }sort前的文件名中提取数字
  • %% { $_.FullName }ForEach-Object的缩写)显示每个文件的完整路径