3

我有一个包含以下数据的文本文件:

12、ABCD

第2541章

4、qwerty

13、尤特鲁

第345章

如何按数字降序对内容进行排序?最好使用批处理。谢谢

4

4 回答 4

5

不能直接排序。我能想到的唯一批处理解决方案是解析并重新创建每一行,其中的数字以零为前缀,宽度恒定。一旦数字具有固定的宽度,您可以使用 SORT 创建一个新的排序文件,然后再使用一个 FOR /F 去除前导零。

我假设 15 位数对于最大的数字就足够了。此解决方案假定所有数字都是大于 0 的整数。

@echo off
set "file=test.txt"
>"%file%.new1" (
  for /f "usebackq tokens=1* delims=," %%A in ("%file%") do (
    set "n=000000000000000%%A"
    set "str=%%B"
    setlocal enableDelayedExpansion
    echo !n:~-15!,!str!
    endlocal
  )
)
>"%file%.new2" sort /r "%file%.new1"
>"%file%" (
  for /f "usebackq tokens=* delims=0" %%A in ("%file%.new2") do echo %%A
)
del "%file%.new?"

如果 0 是原始文件中的值,则必须在最后一步完成额外的工作。如果允许负数,则必须在整个脚本中完成更多工作。

您可以使用 VBScript 或 JavaScript 编写更高效的脚本。

于 2012-09-09T17:51:43.527 回答
3

使用断开连接的记录集的 VBScript 示例。不一定需要更少的代码,但容易维护。

Const ForReading = 1

Const adInteger = 3
Const adVarChar = 200
Const maxChars  = 255

Const sep = ", "

Set fso = CreateObject("Scripting.FileSystemObject")

Set data = CreateObject("ADOR.Recordset")
data.Fields.Append "num", adInteger
data.Fields.Append "txt", adVarChar, maxChars
data.Open

Set f = fso.OpenTextFile("INPUT.TXT", ForReading)
Do Until f.AtEndOfStream
  values = Split(f.ReadLine, sep, 2)
  data.AddNew
  data("num").Value = CInt(values(0))
  data("txt").Value = values(1)
  data.Update
Loop
f.Close

data.Sort = "num DESC"

data.MoveFirst
Do Until data.EOF
  WScript.Echo data("num") & sep & data("txt")
  data.MoveNext
Loop
于 2012-09-09T23:45:46.770 回答
1

最初我不打算发布这个,因为它似乎重复了 dbenham 的回答,但仔细观察让我意识到它并不完全一样(这意味着我不太了解他的内容)所以这是我的,并且“几乎”同样大小!(好吧!这比他的长三分之一,起诉我。^_^)

@echo off
setlocal enabledelayedexpansion
set source=sortme.txt
set tsort=sortme.tmp
set size=0
set zeros=
:: Pass 1
for /f "tokens=1 delims=, " %%x in (sort.txt) do (
   set num=%%x
   call strlen num tsize
   if !tsize! gtr !size! set size=!tsize!
)
for /l %%c in (1,1,%size%) do set zeros=!zeros!0
:: Pass 2
for /f "tokens=1* delims=, " %%x in (sort.txt) do (
  set line=%zeros%%%x
  set line=!line:~-%size%!
  echo !line! %%x, %%y>> sort.tmp
)
endlocal
del sort.txt > nul
:: Pass 3
for /f "tokens=1* delims= " %%x in ('sort /r sort.tmp') do echo %%y>>sort.txt
del sort.tmp > nul

在完成之前,它需要对数据进行三遍,所以它可能会配对一些。

它还利用了来自DOStips.com的STRLEN.BAT

于 2012-09-11T00:37:11.640 回答
1

@dbenham 的答案的变体可用于更快地对文件进行排序,完全在内存中,没有任何临时文件,不需要 ,也不需要sort更改输入的文本。

需要注意的是,文件必须足够小,以使其内容和该算法保持在 32kb 环境内存限制内(请参阅环境内存限制)。

同样,正如@dbenham 的回答一样,该算法需要正整数,大小不超过 15 位。

:: sort-file.BAT
@setlocal
@echo off
set args=%*
if NOT DEFINED args (echo usage: %~dp0 FILE_TO_SORT & exit /b 1)
::
set file=%~1
for /f "usebackq delims=" %%A in ("%file%") do (
    set line=%%A
    for /f "delims=, tokens=1,*" %%G in ("%%A") do (
        set normalized_number=00000000000000%%G
        call set _line_%%normalized_number:~-15%%=%%line%%
        )
    )
for /f "delims== tokens=1,*" %%A in ( 'set _line_' ) do (
    echo %%B
    )
::
于 2018-10-10T05:35:27.547 回答