在 Windows 中使用批处理脚本对文本文件进行排序

时间:2021-02-18 13:22:50

标签: file sorting batch-file

我正在做一个学校项目,我需要使用批处理脚本按用户选择的列对文本文件进行排序。

文件看起来像这样

ID Name Weight Length With Height
052 Chair 1200 100 30 2
077 Bookshelf 5000 120 30 80
096 Cabinet 15000 80 40 85
146 Cupboard 9000 80 60 200
149 Desk 3650 180 100 5
163 Mirror 25800 120 60 70
182 Table 1600 60 60 70

我尝试从这个答案中复制解决方案 Batch sort by column in file

并修改为6列,代码如下:

setlocal DisableDelayedExpansion
(
    for /F "tokens=1-6 delims= " %%A in (%file%) DO (
        set "par1=%%A"
        set "par2=%%B"
        set "par3=%%C"
        set "par4=%%D"
        set "par5=%%E"
        set "par6=%%F"
        setlocal EnableDelayedExpansion
        echo(!par3! !par1! !par2! !par3! !par4! !par5! !par6!
        endlocal
  )
) > data.txt.tmp

for /F "usebackq tokens=1,* delims= " %%A in (`sort data.txt.tmp`) DO (
    echo(%%B
)

所以我遇到的问题是我希望 ID 名称等的顶行保持不变。第二件事是此代码在按 ID 和名称排序时有效,但是当我称重时,它无法正确排序,我得到如下输出:

052 Chair 1200 100 30 2
096 Cabinet 15000 80 40 85
182 Table 1600 60 60 70
163 Mirror 25800 120 60 70
149 Desk 3650 180 100 5
077 Bookshelf 5000 120 30 80
146 Cupboard 9000 80 60 200
ID Name Weight Length With Height

它似乎只是按第一位和第二位数字排序,导致 15000 小于 1600

我怎样才能以最好的方式解决这些问题?

1 个答案:

答案 0 :(得分:0)

我可能会像以下脚本一样完成您的任务(请参阅所有说明):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_FILE=%~1"                      & rem // (file with data to be sorted)
set "_SCOL=3"                        & rem // (number of column to sort)
set "_ANUM=#"                        & rem // (alpha-numeric sorting if not empty)
set "_DESC="                         & rem // (descending order if not empty)
set "_TMPF=%TEMP%\%~n0_%RANDOM%.tmp" & rem // (path to temporary file)
rem // Gather TAB character:
for /F "delims=" %%T in ('
    forfiles /P "%~dp0." /M "%~nx0" /C "cmd /C echo/0x09"
') do set "_TAB=%%T"

rem // Read first line of file into variable:
< "%_FILE%" (set "HEAD=" & set /P HEAD="") || exit /B
rem // Write to temporary file:
> "%_TMPF%" (
    rem // Read all but first line from file line by line:
    for /F usebackq^ skip^=1^ delims^=^ eol^= %%L in ("%_FILE%") do (
        rem // Store current line string:
        set "LINE=%%L"
        rem // Extract sort token from current line:
        for /F "tokens=%_SCOL% delims=%_TAB% eol=%_TAB%" %%K in ("%%L") do (
            rem // Store sort token string:
            set "ITEM=%%K"
            rem // Toggle delayed expansion to avoid loss of `!`:
            setlocal EnableDelayedExpansion
            rem // Check if alpha-numeric sorting is desired:
            if defined _ANUM (
                rem // Check whether sort token only consists of decimal figures:
                (for /F "delims=0123456789 eol=0" %%Z in ("!ITEM!") do rem/) || (
                    rem // Zero-pad sort token to the left up to 12 digits:
                    set "ITEM=000000000000!ITEM!" & set "ITEM=!ITEM:~-12!"
                )
            )
            rem // Write (padded) sort token plus delimter plus line string:
            echo(!ITEM!%_TAB%!LINE!
            endlocal
        )
    )
)
rem // Prepare sort option:
if defined _DESC (set "SOPT=/R") else set "SOPT="
rem // Copy first line, do sorting, strip off sort token, write remainder:
for /F "tokens=1* delims=%_TAB% eol=%_TAB%" %%K in ('
    cmd /V /C echo(_!_TAB!!HEAD!^& rem/ ^& ^
        sort %SOPT% "%_TMPF%"
') do echo(%%L
rem // Clean up temporary file:
del "%_TMPF%"

endlocal
exit /B

文本文件的路径/名称需要作为命令行参数提供。

相关问题