Windows 按编号对文本文件的内容进行排序

Windows 按编号对文本文件的内容进行排序,windows,batch-file,vbscript,Windows,Batch File,Vbscript,我有一个包含以下数据的文本文件: 12,abcd 2541,香港特别行政区 4、qwerty 13,uytrew 345,iuoiyt 如何按数字降序排列内容?最好使用批处理。谢谢您不能直接排序。我能想到的唯一批处理解决方案是解析并重新创建每一行,其中数字前缀为零,宽度不变。一旦数字具有固定的宽度,就可以使用SORT创建一个新的排序文件,然后再使用一个FOR/F来去掉前导的零 我假设15位数字足够容纳最大的数字。此解决方案假定所有数字都是大于0的整数 @echo off set "file=te

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

12,abcd

2541,香港特别行政区

4、qwerty

13,uytrew

345,iuoiyt


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

您不能直接排序。我能想到的唯一批处理解决方案是解析并重新创建每一行,其中数字前缀为零,宽度不变。一旦数字具有固定的宽度,就可以使用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编写效率更高的脚本。

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

起初我不打算发布这篇文章,因为它似乎重复了dbenham的答案,但仔细一看,我意识到它其实并不完全相同(意思是我不太理解他的),所以这是我的,而且“几乎”大小也一样!(好吧!比他的长了三分之一,告我吧。)

在完成之前,需要对数据进行三次传递,因此可能需要对数据进行一些配对

它还利用了from

的一个变体,可用于更快地对文件进行排序,完全在内存中,无需任何临时文件,无需对进行排序,也无需更改输入的文本

需要注意的是,文件必须足够小,以使其内容和此算法保持在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
    )
::

正如dbenham所说,为什么不使用脚本呢?数字应该是整数,这似乎是不言而喻的。尽管如此,我还是大胆地在你的回答中明确指出了这一点,希望你不会介意@安德烈-无可争辩:-)谢谢大家-这很有效,但速度非常慢。带有20行的Test.txt此bat文件大约持续2分钟。再次感谢:-)@Gabil-嘿,我知道批量文本处理相对较慢,这就是为什么我说可以使用VBS编写更高效的脚本。但是20排2分钟????你的机器出毛病了。我刚刚用这个脚本处理了一个61485字节的文件,其中包含1572行,仅用了1秒多的时间。编辑-我将排序改为降序,当我第一次阅读这个问题时,我错过了这个要求。嗨,Ansgar,谢谢你的快速回复。我知道这段代码从input.txt文件中获取输入。但产出呢?在哪里可以看到已排序的字符串?我已经运行了这个脚本,但没有任何更改。谢谢:-)@Gabil现在只是在重复输出。如果希望将其写入文件,只需使用该方法即可。记录集按指令
data.Sort=“num DESC”
排序。如果只需要不带数字的字符串,请仅输出
data(“txt”)
,而不是
data(“num”)&sep&data(“txt”)
。您可以按原样使用脚本,只需在批处理文件中重定向输出,如下所示,
CSCRIPT Sorter.vbs>SortedText.txt
+1,但是,如果字符串包含分隔符,则应将count参数添加到Split中:
Split(f.ReadLine,sep,2)
:: 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
    )
::