如何从linux命令行对文件进行数字排序

如何从linux命令行对文件进行数字排序,linux,command-line,sorting,Linux,Command Line,Sorting,好吧,现在这更多的是关于Linux的咆哮而不是一个问题,但也许有人知道如何做我想做的事情。我知道这可以通过使用sort命令来实现,但我想要一个更好的解决方案,因为实现这一点就像编写一个C程序来完成同样的任务一样简单 我有文件,为了论证,让我们假设我有这些文件:(我的文件是一样的,我只是有更多) file-10.xml 文件-20.xml file-100.xml file-k10.xml file-k20.xml 文件-k100.xml file-M10.xml file-M20.xml fi

好吧,现在这更多的是关于Linux的咆哮而不是一个问题,但也许有人知道如何做我想做的事情。我知道这可以通过使用
sort
命令来实现,但我想要一个更好的解决方案,因为实现这一点就像编写一个C程序来完成同样的任务一样简单

我有文件,为了论证,让我们假设我有这些文件:(我的文件是一样的,我只是有更多)

  • file-10.xml
  • 文件-20.xml
  • file-100.xml
  • file-k10.xml
  • file-k20.xml
  • 文件-k100.xml
  • file-M10.xml
  • file-M20.xml
  • file-M100.xml
这就是我想让他们分类的顺序。顺便说一句,这是默认情况下它们在窗口中的排序顺序。那很好。Windows将连续的数字字符分组为一个有效字符,该字符在字母之前按字母顺序排序

如果在linux命令行中键入
ls
,则会得到以下垃圾。请注意,20已移位。这是一个更大的交易,当我有数百个这样的文件,我想在报告中查看,为了

  • file-100.xml
  • file-10.xml
  • 文件-20.xml
  • 文件-k100.xml
  • file-k10.xml
  • file-k20.xml
  • file-M100.xml
  • file-M10.xml
  • file-M20.xml
我可以使用
ls-1 | sort-n-k1.6
获得没有“k”或“M”的正确值

  • 文件-k100.xml
  • file-k10.xml
  • file-k20.xml
  • file-M100.xml
  • file-M10.xml
  • file-M20.xml
  • file-10.xml
  • 文件-20.xml
  • file-100.xml
我可以使用
ls-1 | sort-n-k1.7
来纠正所有错误

  • file-100.xml
  • file-10.xml
  • 文件-20.xml
  • file-k10.xml
  • file-M10.xml
  • file-k20.xml
  • file-M20.xml
  • 文件-k100.xml
  • file-M100.xml
好的,很好。让我们真正把它做好
ls-1 | grep“file-[0-9]*\.xml”| sort-n-k1.6&&ls-1 file-k*.xml | sort-n-k1.7&&ls-1 file-M*.xml | sort-n-k1.7

  • file-10.xml
  • 文件-20.xml
  • file-100.xml
  • file-k10.xml
  • file-k20.xml
  • 文件-k100.xml
  • file-M10.xml
  • file-M20.xml
  • file-M100.xml
唷!男孩很高兴“linux命令行的力量”救了我一命。(对于我的情况,这是不实际的,因为我的命令不是
ls-1
,而是另一行或两行)

现在,Windows的行为简单、优雅,99%的时间都能完成您希望它完成的任务。为什么我不能在linux中使用它?为什么
sort
没有一个“自动排序数字,不会让我撞到墙上”开关

下面是C++的伪代码:

bool compare_two_strings_to_avoid_head_injury(string a, string b)
{
    string::iterator ai = a.begin();
    string::iterator bi = b.begin();
    for(; ai != a.end() && bi != b.end(); ai++, bi++)
    {
        if (*ai is numerical)
            gobble up the number incrementing ai past numerical chars;
        if (*bi is numerical)
            gobble up the number incrementing bi past numerical chars;
        actually compare *ai and *bi and/or the gobbled up number(s) here
            to determine if we need to compare more chars or can return the 
            answer now;
    }
    return something here;
}

这么难吗?有人能把这个分类并寄给我一份吗?请?

ls-1v
会让你离得很近。它只是将所有大写字母排序在小写之前。

这是我的第一个想法:

ls -1 | sed 's/\-\([kM]\)\?\([0-9]\{2\}\)\./-\10\2./' | sort | sed 's/0\([0-9]\{2\}\)/\1/'
基本上,我只是使用sed将数字填充为零,然后再使用它去掉前导的零

我不知道用Perl是否会更快。

试试看 sort—版本sort-f

  • file-10.xml
  • 文件-20.xml
  • file-100.xml
  • file-k10.xml
  • file-k20.xml
  • 文件-k100.xml
  • file-M10.xml
  • file-M20.xml
  • file-M100.xml

f选项是忽略大小写(否则,在本例中,它会将k和M按错误的顺序排列)。但是,如果这是你的目标的话,我不认为sort不能正确地将字母k和M解释为成千上万,这只是字母顺序。

你可以用前导零将数字字段填充到相同的长度,从而省去一点麻烦,而不是依赖特定于平台的怪癖来获得您想要的排序顺序。我要指出的是,也许Windows行为在99%的时间里做了你想让它做的事情,但说它在99%的时间里做了每个人想做的事情是不公平的。事实上,我也可以对Windows的排序提出与Linux排序相同的抱怨。(如果能将其作为排序的选项,那就太好了)这里的编程问题是什么?如果您只想对文件名进行排序,可能会有人提供帮助。Windows并不总是这样排序。请参阅@Scott:yes,您确实使用了一个特定于平台的怪癖,即
dir
将连续数字分组为一个“有效字符”,而
ls
没有。尽管从技术上讲,这是
dir
程序的一个怪癖,而不是Windows。类似地,您所说的Linux问题实际上是一个特定程序的“问题”
sort
。(此外,这并不是一个问题,正如一个合法的bug是一个问题一样,它只是一个与您的需求不匹配的设计决策。这在每个平台上都会不时发生。)根据您的建议,这就是我最终要做的。我有这个,因为我在'ls-1$1*.xml | sed-r的/-([kM]?)([0-9]{4})\./-\10\2./;中需要最多4位数字
;s/-([kM]?)([0-9]{3})\./-\100\2./;s/-([kM]?)([0-9]{2})\./-\1000\2./;s/-([kM]?)([0-9]{1})\./-\10000\2./'| sort | sed-r's/0+([1-9])/\1/'`;做
,对于这么简单的任务,我觉得这是非常可笑的。这是IMO排序的一大失败。比选择的答案好得多的解决方案…我想可能不太便于携带
-V
--版本排序
的短标志,仅供参考。这也适用于具有不同数字大小的数字:
1 2 3。。。12 13 14 ... 123 124 125 ... 1123 1124 1125…