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

时间:2012-09-09 17:15:55

标签: windows batch-file vbscript

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

  

12,abcd

     

2541,sdfrhk

     

4,qwerty

     13,uytrew

     

345,iuoiyt

如何按降序对内容进行排序?优选使用批次。感谢

4 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:3)

使用已断开连接的recordset的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

答案 2 :(得分: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

在数据完成之前需要三次传递,所以它可能会配对一些。

它还利用STRLEN.BAT

中的DOStips.com

答案 3 :(得分:0)

可以使用@dbenham's answer的一种变体来更快地,完全在内存中对文件进行排序,而不需要任何临时文件,不需要sort,并且无需更改输入文本。 / p>

需要注意的是,文件必须足够小以使其能够容纳内容,并且该算法应保持在32kb环境内存限制内(请参见environment memory limits)。

同样,如@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
    )
::