batch-file - cmd命令以数字顺序转储文件列表

标签 batch-file cmd

抱歉,我无法正确表达,但我需要一个命令来创建一个文本文件,以数字顺序转储文件名。这是执行我想要的操作的命令,但开头有 1 的所有内容都被捆绑在一起,2、3 等等......

(for %i in (*.flv) do @echo file '%i') > file.txt

最佳答案

大多数 cmd/batch 文件命令,例如 dirsortset,执行纯按字母顺序排序,因此不会特别处理任何数字部分。例如,string12出现在string3之前,因为字符1出现在2之前,使用排序方式。要更改行为以便应用字母数字排序,这意味着 string3 出现在 string12 之前,您必须编写自己的代码来实现它。下面的脚本正是这样做的,通过将字符串/文件名中出现的每个数字部分填充到固定数量的数字,在这种情况下,字母数字和字母排序顺序匹配。下面是代码,包括注释。如您所见,需要复杂的代码来完成任务并使脚本免受对 cmd 具有特殊含义的所有字符(如 SPACE, ;. = 以及^, &, (, ), %, !):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_TEMPFILE=%TEMP%\%~n0_%RANDOM%.tmp" & rem // (temporary file used for sorting)
set /A "_DIGITS=12" & rem // (number of digits every numeric part is padded for sorting)

rem // Build string containing enough zeros for padding:
set "$PAD=" & setlocal EnableDelayedExpansion
for /L %%D in (1,1,%_DIGITS%) do set "$PAD=!$PAD!0"
endlocal & set "$PAD=%$PAD%"

rem // Prepare temporary file containing data to sort:
> "%_TEMPFILE%" (
    rem // Gather and resolve all command line arguments:
    for %%I in (%*) do (
        rem // Get pure file name:
        set "ITEM=%%~nxI"
        rem // Extend all numeric parts in file name to certain number of digits:
        call :PROCESS AUGM ITEM || >&2 echo ERROR: potential problem sorting "%%~nxI"!
        rem // Write extended and original file name into temporary file:
        setlocal EnableDelayedExpansion
        echo(!AUGM!^|!ITEM!
        endlocal
    )
)

rem // Return content of temporary file in ascendingly sorted order:
for /F "tokens=2 delims=| eol=|" %%J in ('sort "%_TEMPFILE%"') do (
    rem // Simply return each item:
    echo(%%J
)

rem // Delete temporary file:
del "%_TEMPFILE%"

endlocal
exit /B


:PROCESS  rtn_augmented_string  ref_string
rem /* Routine to augment a string so that every numeric part is padded with leading
rem    zeros to the left to hold a predefined number of digits: */
setlocal DisableDelayedExpansion
set "#RTN=%~1"
set "#ARG=%~2"
rem // Initialise required variables:
set "COLL="
set "ERRL=0"
setlocal EnableDelayedExpansion
for /F delims^=^ eol^= %%B in (^""!%#ARG%!"^") do (
    endlocal
    set "PSTR=%%~B"
    setlocal EnableDelayedExpansion
)
rem // Entry point for loop to handle one numeric string part:
:REPEAT
rem // Extract the string portions before and after the first numeric part:
for /F "tokens=1,* delims=0123456789 eol=0" %%A in ("+!PSTR!") do (
    endlocal
    set "PART=%%A"
    set "NEXT=%%B"
    rem // Determine length of string portion before first numeric part:
    call :LENGTH PLEN PART
    set /A "PLEN-=1"
    setlocal EnableDelayedExpansion
    set "PART=!PART:~1!"
    rem // Split off string portion before first numeric part from total string:
    for %%C in (!PLEN!) do (
        if defined PSTR set "PSTR=!PSTR:~%%C!"
    )
    rem /* Splitt off string portion after first numeric part from remaining string;
    rem    this is nothing but extracting the first numeric part itself: */
    call :SPLIT PNUM NEXT PSTR
    rem // Determine the actual length of the numeric part:
    call :LENGTH NLEN PNUM
    rem // Do the actual padding with leading zeros of the numeric part:
    if defined PNUM (
        set "PNUM=%$PAD%!PNUM!"
        set "PNUM=!PNUM:~-%_DIGITS%!"
    )
    rem // Store the part after the first numeric part:
    for /F delims^=^ eol^= %%C in (^""!NEXT!"^") do (
        rem /* Build string with the string portion before the current numeric part
        rem    and the padded current numeric part itself: */
        for /F delims^=^ eol^= %%D in (^""!COLL!!PART!!PNUM!"^") do (
            rem // Check whether the predefined number of padding digits is sufficient:
            for /F %%E in ("!NLEN!") do (
                endlocal
                set "PSTR=%%~C"
                set "COLL=%%~D"
                if %%E GTR %_DIGITS% set "ERRL=1"
                setlocal EnableDelayedExpansion
            )
        )
    )
)
rem // Repeat the whole approach while there is still a remaining string portion:
if defined PSTR goto :REPEAT
rem // Return the string with padded numeric parts:
for /F delims^=^ eol^= %%R in (^""!COLL!"^") do (
    endlocal
    endlocal
    set "%#RTN%=%%~R"
    exit /B %ERRL%
)
exit /B


:SPLIT  rtn_left_string  ref_split_char  val_string
rem /* Routine to split a string at the first occurrence of a certain character and to
rem    return the portion before it: */
setlocal DisableDelayedExpansion
set "#RTN=%~1"
set "#CHR=%~2"
set "#ARG=%~3"
rem // Initialise required variables:
setlocal EnableDelayedExpansion
set "CHAR= " & if defined %#CHR% set "CHAR=!%#CHR%:~,1!"
if "!CHAR!"=="<" (set "PREF=>") else (set "PREF=<")
rem // Check whether a split character is defined:
if defined %#CHR% (
    rem /* Split character available, so split off first occurrence and everything after
    rem    from the original string: */
    for /F eol^=^%CHAR%^ delims^=^%CHAR% %%C in ("%PREF%!%#ARG%!") do (
        endlocal
        set "%#RTN%=%%C"
        setlocal EnableDelayedExpansion
        set "%#RTN%=!%#RTN%:~1!"
    )
) else (
    rem // No split character defined, so do not split off anything:
    set "%#RTN%=!%#ARG%!"
)
rem // Return the resulting string:
for /F delims^=^ eol^= %%R in (^""!%#RTN%!"^") do (
    endlocal
    endlocal
    set "%#RTN%=%%~R"
)
exit /B


:LENGTH  rtn_length  ref_string
rem /* Routine to determine the length of a given string: */
setlocal DisableDelayedExpansion
set "#RTN=%~1"
set "#ARG=%~2"
setlocal EnableDelayedExpansion
rem // Check whether a string is provided:
if defined %#ARG% (
    rem // String is available, so calculate its length:
    set /A "%#RTN%=1"
    for %%A in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
        if not "!%#ARG%:~%%A!"=="" (
            set /A "%#RTN%+=%%A"
            set "%#ARG%=!%#ARG%:~%%A!"
        )
    )
) else (
    rem // String is empty, so length is zero:
    set /A "%#RTN%=0"
)
rem // Return the computed length:
for /F %%R in ("!%#RTN%!") do (
    endlocal
    endlocal
    set "%#RTN%=%%R"
)
exit /B

提供 (a) 文件模式作为 (a) 命令行参数,例如(假设批处理文件保存为 sort-alpha-num.bat ):

sort-alpha-num.bat "*.flv"

要将生成的排序列表存储在名为 file.txt 的文本文件中,请使用:

sort-alpha-num.bat "*.flv" > "file.txt"

如果出现类似 ERROR: potential problem sorting "1000000000000.flv"! 的错误消息,请增加脚本顶部的位数(参见行 set/A "_DIGITS =12").

关于batch-file - cmd命令以数字顺序转储文件列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40077559/

相关文章:

npm - Electron抛出了编译错误,并且Windows命令提示符变为不可写

excel - Zip 批处理命令和 Excel

windows - 批处理文件中的 For 循环错误地从文件读取输入 - 循环失败

batch-file - 获取文件中的结果计数(按前 3 个字符)。

windows - Windows批处理如何同时调用内部函数?

windows - 如何获取powerscript版本并在批处理脚本中升级?

javascript - 这个 Windows 批处理文件如何运行嵌入式 javascript?

selenium - 如何关闭 Selenium Grid2 服务器?

windows - 如何在使用 WinRAR 创建多个 ZIP 压缩文件时显示丢失文件列表和其他错误?

windows - 生成帮助文件