使用批处理脚本时如何克服关于文件名的ASCII排序顺序?

时间:2013-04-09 20:21:03

标签: javascript sorting vbscript batch-file

我有一个批处理脚本调用jscript文件(下面的链接)将excel工作簿表保存为csv文件。 http://gotochriswest.com/blog/2011/05/05/excel-batch-convert-xls-to-csv/

然后我使用批处理脚本将这些文件合并在一起。但是,如果我遇到名为

的文件
  

文件1

     

file2的

     

file10

     

FILE11

然后文件将按以下顺序合并:

  

文件1

     

file10

     

FILE11

     

file2的

按此顺序提供信息并不令人满意。

是否有人知道使用批处理或任何其他脚本语言的方法,这些语言可以在典型的Windows计算机上运行(例如JScript / VBscript),允许文件以“人类”顺序合并?

我尝试实施的方法如下: 如果文件名包含数字,则确定该数字包含的位数,并相应地添加零。例如。 file1将成为file001

这已经惨遭失败,反复失败。可以这样做吗?还有更好的方法吗?

4 个答案:

答案 0 :(得分:2)

添加前导零的方法应该有效 - 它究竟是如何失败的?

这些文件名是如何生成的?他们只是序号,还是随意的?如果它们是连续的,您不必计算最大位数,而是可以选择一个常数,让我们说总共10位数。如果你做10,那么算法只会在你有超过10 000 000 000个文件需要处理的情况下中断,我希望这不会发生

答案 1 :(得分:1)

此脚本将前导零添加到文件名。将文件名的长度设置为%pre%变量中的零数。不会处理长度更长的文件名。如果存在文件名alredy,则会发生错误。查看输出并在echo之前删除ren命令,如果没有问题。

@echo off&setlocal
set "pre=0000000000" &rem max filename length-1

for /f "delims=:" %%i in ('^(@echo(%pre%^&@echo(^)^|findstr /o $') do set /a MinNameLength=%%i-3
for %%i in (*) do (
    set "fname=%%~ni"
    setlocal enabledelayedexpansion
    for /f "delims=:" %%i in ('^(@echo(!fname!^&@echo(^)^|findstr /o $') do set /a fnamelen=%%i-3
    if !fnamelen! lss %MinNameLength% (
        set "fname=%pre%!fname!
        set "fname=!fname:~-%MinNameLength%!
        echo ren "%%~fi" "!fname!%%~xi"
    ) else (
    echo file name too long: %%~nxi
    )
    endlocal
)
endlocal

我建议您复制文件而不是重命名文件!

答案 2 :(得分:0)

有多种方法可以按不区分大小写的顺序对字符串数组(如文件名)进行排序,数字按值而不是按字符排序。 这个适用于大型阵列,以及大多数小型阵列。

Array.prototype.naturalSort= function naturalSort(index){
    var T= this, L= T.length, i, who, next,
    isi= typeof index== 'number',
    rx=/(\.\d+)|(\d+(\.\d+)?)|([^\d.]+)|(\.\D+)|(\.$)/g;
    function nSort(aa, bb){
        var a= aa[0], b= bb[0], a1, b1, i= 0, n, L= a.length;
        while(i<L){
            if(!b[i]) return 1;
            a1= a[i];
            b1= b[i++];
            if(a1!== b1){
                n= a1-b1;
                if(!isNaN(n)) return n;
                return a1>b1? 1:-1;
            }
        }
        return b[i]? -1:0;
    }
    for(i= 0;i<L;i++){
        who= T[i];
        next= isi? T[i][index] || '':who;
        T[i]= [String(next).toLowerCase().match(rx), who];
    }
    T.sort(nSort);
    for(i= 0;i<L;i++){
        T[i]= T[i][1];
    }
}

如果需要,您可以重写它以将其从Array原型中取出并传入数组。

答案 3 :(得分:0)

如果所有文件都具有相同的命名方案,即来自&#34; file1&#34;到&#34; file999&#34;然后很容易(而且快!)来实现这样的重命名。下面的批处理文件有两个参数:文件名的固定部分和新名称中所需的位数。例如,renumber.bat file 4会生成新名称,例如&#34; file0001&#34;,&#34; file0002&#34; ... to&#34; file0999&#34;。

@echo off
for %%a in ("%~1*.*") do (
   set "name=%%~Na"
   setlocal EnableDelayedExpansion
   set number=0000000000!name:%~1=!
   ECHO ren "%%a" "%~1!number:~-%2!%%~Xa"
   endlocal
)

编辑添加了可选方法

另一方面,下面的批处理文件在他的答案中建议在Endoro的名称中插入前导零。在这种情况下,将新名称的 total lenght 放在第一个参数中;原始的较长名称将不会被处理。

@echo off
for %%a in (*.*) do (
   set name=0000000000000000%%a
   setlocal EnableDelayedExpansion
   set newName=!name:~-%1!
   if "!newName:~0,1!" equ "0" ECHO ren "%%a" "!newName!"
   endlocal
)