如何在Windows批处理中为图像序列添加前导零?

时间:2015-11-26 11:57:10

标签: batch-file

我发现this link解释了如何将前导零添加到数字序列中:

@echo off
set count=5
setlocal EnableDelayedExpansion
for /L %%i in (1, 1, %count%) do (
     set "formattedValue=000000%%i"
     echo !formattedValue:~-6!
)

此输出

000001
000002
000003
000004
000005

我的图像序列如下所示:

%1.j2c_0.j2c
%1.j2c_10.j2c
%1.j2c_100000.j2c

我想总是有6个号码:

%1.j2c_000000.j2c
%1.j2c_000010.j2c
%1.j2c_100000.j2c

最后一个下划线之前的文件名可以更改并包含更多下划线。 所以我想我需要找出最后一个下划线右边有多少个数字,并添加正确数量的零以获得6个数字。 我该怎么做?

2 个答案:

答案 0 :(得分:2)

据我了解你的问题,图像文件的模式是*_*.j2c

由于前导文件名部分可能包含多个_,因此可以使用一个技巧:for提供了通过提供~修饰符将迭代项目拆分为多个部分的可能性;假设变量为%I,则%~nI会返回文件名,%~xI扩展名为%~nxI文件名加扩展名(请参阅for /?)。
如果没有使用通配符*?,则无需访问文件系统即可完成拆分;所以我们可以将它用于字符串操作操作。为了将此应用于我们手头的任务,我们需要将每个_替换为路径分隔符\
有两个嵌套的for循环;外部的一个遍历所有的图像文件,内部的一个接收每个文件名加上ext。从外部迭代一次,其中路径字符串拆分功能(mis-)用于我们的需要。

以下代码片段使用所描述的技巧在文件名的最后_之后提取部件,然后是用6个前导零填充的数字。另见解释性rem评论:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "IMAGES=*_*.j2c"
set "DIGITS=6" & rem add more padding `0`s below if DIGITS > 12!
rem loop through all images that match the pattern given above;
rem since there is a wildcard `*`, the file system is accessed:
for %%I in ("%IMAGES%") do (
    rem now let us extract the portion between the last `_` and the ext.;
    rem for this we replace every `_` by `\`, so the item looks like a file path;
    rem then we split off the file name portion of the path-like string;
    rem since there are no more wildcards, the file system is NOT accessed:
    set "ARG=%%~nxI"
    set "FPTH=%%~fI"
    setlocal EnableDelayedExpansion
    for %%F in ("!ARG:_=\!") do (
        rem extract and pad the numeric file name portion:
        set "VAL=000000000000%%~nF"
        set "VAL=!VAL:~-%DIGITS%!"
        rem rebuild file name; the `|` ensures that only the part
        rem after the last `_` is replaced by the padded number:
        setlocal DisableDelayedExpansion
        set "ARG=%%~F|"
        setlocal EnableDelayedExpansion
        set "ARG=!ARG:%%~nxF|=!!VAL!%%~xF"
    )
    ren "!FPTH!" "!ARG:\=_!"
    endlocal
    endlocal
    endlocal
)
endlocal

这种方法的最大优点是我们不需要知道_个字符的数量(与for /F "tokens=1,2 delims=_"相对应,其中标记的数量是固定的。)

答案 1 :(得分:1)

这有点挑战(但有点):

@echo off
setlocal enableDelayedExpansion

:: path to the directory with the files
set "files_dir=."
pushd "%files_dir%"
for %%# in (*_*j2c) do (
    set "filename=%%~nx#"
    for /f "tokens=1,2,3,4 delims=_." %%A in ("!filename!") do (
        set "num=%%C"
        call ::strlen0 num numlen
        if !numlen! LSS 6 (

            for /l %%] in (!numlen! ; 1 ; 6 ) do (
                set "num=0!num!"
            )

            ren %%A.%%B_%%C.%%D  %%A.%%B_!num!.%%D

        ) else (
           echo %%# will be not processed - more than or 6 numbers
        )
    )
)

endlocal & (
    popd
    exit /b %errorlevel%
)

:: taken from http://ss64.org/viewtopic.php?id=424
:strlen0  StrVar  [RtnVar]
  setlocal EnableDelayedExpansion
  set "s=#!%~1!"
  set "len=0"
  for %%N in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
    if "!s:~%%N,1!" neq "" (
      set /a "len+=%%N"
      set "s=!s:~%%N!"
    )
  )
  endlocal&if "%~2" neq "" (set %~2=%len%) else echo %len%
exit /b