查找前面带有变量零的下一个文件夹编号

时间:2015-12-18 17:25:04

标签: batch-file

我正在尝试编写一个批处理文件,该文件将在包含多个具有顺序项目编号和仲裁名称的文件夹的目录中查找,例如:

0001 - ProjectA
0002 - ProjectB
.....
0009 - ProjectX
0010 - ProjectY 

并计算下一个项目编号(目的是创建一个包含下一个项目编号的新文件夹)。这是我到目前为止所得到的:

cls

setlocal 

cd /d c:\Test

for /f "tokens=1 delims= " %%1 in ('dir /b /ad /on') do (set latestdir=%%1)

echo %latestdir%

set /a nextdir=%latestdir% + 1

echo %nextdir% 

pause

我注意到如果前面0的数量不同,这种方法就会失败。即用00010更改0010,找到004作为最后一个文件夹。我已经尝试了很多东西和网络上的代码片段,以删除前面的0并取消效果,但没有运气。

此目录还将包含不以数字开头的非项目文件夹。

任何指针都会非常感激!

3 个答案:

答案 0 :(得分:1)

@echo off
setlocal

rem Get last folder that start with digit (i.e. 0010)
cd /d c:\Test
for /L %%i in (0,1,9) do (
   for /f "tokens=1 delims= " %%a in ('dir /b /ad /on %%i*') do set "latestdir=%%a"
)
echo %latestdir%

rem Get next number preceded by 1 (i.e. 10010+1=10011)
set /a nextdir=1%latestdir%+1

rem Show the number removing first digit (i.e. 0011)
echo %nextdir:~1%

编辑:如果数字可能有一个可变位数,并且您想强制输出4位数字,那么您可以改用此方法:

rem Show the last four digits in number (i.e. 0011)
echo %nextdir:~-4%

但是,如果数字 less 而不是4位数,则此方法将失败...

答案 1 :(得分:0)

我们在Dostips.com上有一个名为SORTN的批处理文件,可以帮助进行数字排序。我在这里发布代码给后人。

@ECHO OFF
if "%~1"=="/?" (
    echo.Sorts text by handling first number in line as number not text
    echo.
    echo.%~n0 [n]
    echo.
    echo.  n     Specifies the character number, n, to
    echo.        begin each comparison.  3 indicates that
    echo.        each comparison should begin at the 3rd
    echo.        character in each line.  Lines with fewer
    echo.        than n characters collate before other lines.
    echo.        By default comparisons start at the first
    echo.        character in each line.
    echo.
    echo.Description:
    echo.        'abc10def3' is bigger than 'abc9def4' because
    echo.        first number in first string is 10
    echo.        first number in second string is 9
    echo.        whereas normal text compare returns 
    echo.        'abc10def3' smaller than 'abc9def4'
    echo.
    echo.Example:
    echo.        To sort a directory pipe the output of the dir
    echo.        command into %~n0 like this:
    echo.           dir /b^|%~n0
    echo.
    echo.Source: http://www.dostips.com
    goto:EOF
)
if "%~1" NEQ "~" (
    for /f "tokens=1,* delims=," %%a in ('"%~f0 ~ %*|sort"') do echo.%%b
    goto:EOF
)
SETLOCAL ENABLEDELAYEDEXPANSION
set /a n=%~2+0
for /f "tokens=1,* delims=]" %%A in ('"find /n /v """') do (
    set f=,%%B
    (
        set f0=!f:~0,%n%!
        set f0=!f0:~1!
        rem call call set f=,%%%%f:*%%f0%%=%%%%    
        set f=,!f:~%n%!
    )
    for /f "delims=1234567890" %%b in ("!f!") do (
        set f1=%%b
        set f1=!f1:~1!
        call set f=0%%f:*%%b=%%
    )
    for /f "delims=abcdefghijklmnopqrstuwwxyzABCDEFGHIJKLMNOPQRSTUWWXYZ~`@#$*_-+=:;',.?/\ " %%b in ("!f!") do (
        set f2=00000000000000000000%%b
        set f2=!f2:~-20!
        call set f=%%f:*%%b=%%
    )
    echo.!f1!!f2!!f!,%%B
    rem echo.-!f0!*!f1!*!f2!*!f!*%%a>&2
)

所以这是使用DIR命令并将其传送到SORTN时的输出以及正常DIR命令的输出。

C:\BatchFiles\SORTN>dir /ad /b 00* |sortn.bat
0001 - ProjectA
0002 - ProjectB
0004 - ProjectC
00010 - ProjectY

C:\BatchFiles\SORTN>dir /ad /b 00*
0001 - ProjectA
00010 - ProjectY
0002 - ProjectB
0004 - ProjectC

将MY DIR代码插入FOR / F命令。 更新为删除前导零。

@echo off
for /f "tokens=1 delims= " %%G in ('dir /b /ad 0* ^|sortn.bat') do set latestdir=%%G

:STRIP0
IF "%latestdir:~0,1%"=="0" (
    SET latestdir=%latestdir:~1%
    GOTO STRIP0
)
echo %latestdir%
pause

再添加一个不使用SORTN.BAT的选项

@echo off
setlocal EnableDelayedExpansion
set "latestdir="
for /D %%j in (0* 1* 2* 3* 4* 5* 6* 7* 8* 9*) do (
   FOR /F "tokens=1 delims= " %%G IN ("%%j") DO set num=%%G
   set j=0000000!num!
   set name[!j:~-8!]=%%~nxj
)
for /F "tokens=2 delims== " %%j in ('set name[') do set latestdir=%%j

:STRIP0
IF "%latestdir:~0,1%"=="0" (
    SET latestdir=%latestdir:~1%
    GOTO STRIP0
)
echo %latestdir%

pause

答案 2 :(得分:0)

以下是检索目录中最新(最大)数字并返回下一个数字的固定代码:

@echo off
cls
setlocal EnableExtensions DisableDelayedExpansion
cd /D "C:\Test"
for /F "tokens=1 delims= " %%D in ('
    dir /B /A:D /O:-N "???? - *"
') do (
    set "latestdir=%%~D"
    goto :NEXT
)
:NEXT
for /F "tokens=* delims=0" %%N in ("%latestdir%") do (
    set "latestdir=%%~N"
)
echo "%latestdir%"
set /A "nextdir=latestdir + 1"
set "nextdir=000%nextdir%"
set "nextdir=%nextdir:~-4%"
echo "%nextdir%"
pause
endlocal

我做了什么:

  • 模式???? - *已添加到dir,因此只返回此类目录:4个字符,后跟 SPACE - SPACE < / kbd>,后跟任何东西;这不会检查4个前导字符是否是数字;
    • 如果您确实要检查前4位是纯数字,请将^| findstr /R "^[0-9][0-9][0-9][0-9]"附加到dir命令行(只有在^|内使用for /F时才需要| 1}}与上面的代码一样;当单独使用时,只需要状态dir);
  • /O:-N的排序顺序已被反转(goto),因此首先返回最新目录; for /F打破for /F循环,因此只处理第一个目录;这可能会改善整体表现;
  • 添加了第二个0循环,从%latestdir%移除了所有前导set /A;这是必要的,因为set /A将带有前导零的数字视为八进制数,这可能会导致意外结果;
  • 1之后,它按for /F递增以获取下一个目录索引(即使最新的数字为空意味着零,也不会失败,因为前面的{{1} } loop,再插入两个set命令行:
    1. 第一个在000之前到数字%nextdir%;
    2. 下一个使用子字符串扩展语法并返回最后4个数字;
  • 一般来说,set语法已得到改进,已添加了"";

注意:
目录的排序依赖于这样的事实:数字前缀全部由相同的数字组成,因为dir 能够进行真正的字母数字排序,它只是按字母顺序排序(或在技​​术上说,通过字符代码)。

编辑:

这是一个解决方案,不再坚持由4位数组成的数字,因此它们现在最多可包含12位数字。由于dir /O执行字母排序而不是字母数字排序,因此/O开关已被删除。检索到的数字用零填充,每个由12个数字组成,然后set用于实际排序,也以字母方式排序,但由于填充,这提供了与字母数字排序完全相同的结果。要使用set进行排序,我会利用它返回一个排序的环境变量列表的事实,如果只给出一个变量名前缀。这里我使用currentdir_作为前缀,之后我为每个迭代项创建了一个变量,其名称为currentdir_,并附加了填充的数字部分。作为值,存储没有任何前导零的纯数值。在解析set返回的排序列表时,每个项目都以=字符分割,后跟所述数值。最后一个构成最大的那个,然后用于计算下一个数字:

@echo off
cls
setlocal EnableExtensions DisableDelayedExpansion
cd /D "C:\Test"
for /F "tokens=1 delims= " %%D in ('
    dir /B /A:D "* - *" ^| findstr /R /C:"^[0-9][0-9]* - "
') do (
    set "currentdir=00000000000%%~D"
    for /F "tokens=* delims=0" %%Z in ("%%~D") do (
        if "%%~Z"=="" (
            call set "currentdir_%%currentdir:~-12%%=0"
        ) else (
            call set "currentdir_%%currentdir:~-12%%=%%~Z"
        )
    )
)
for /F "tokens=2 delims==" %%N in ('set "currentdir_"') do (
    set "latestdir=%%~N"
)
echo "%latestdir%"
set /A "nextdir=latestdir + 1"
set "nextdir=000%nextdir%"
set "nextdir=%nextdir:~-4%"
echo "%nextdir%"
pause
endlocal