2010-07-24 80 views
14

好吧,现在这更多的是关于Linux而不是一个问题,但也许有人知道如何做我想做的事情。我知道这可以实现使用sort命令,但我想要一个更好的解决方案,因为得到它的工作就像编写一个C程序来做同样的事情一样简单。如何从Linux命令行数字排序文件

我所拥有的文件,为了讨论各种情形,可以说我有这些文件:(我的文件是相同的我只是有更多)

  • 文件10.xml
  • 文件20.xml
  • 文件100.xml
  • 文件k10.xml
  • 文件k20.xml
  • 文件k100.xml
  • ˚F ILE-M10.xml
  • 文件M20.xml
  • 文件M100.xml

现在,这原来是我希望他们的排序顺序。顺便说一句,这是为了在Windows他们默认分类到。这很好。 Windows将连续的数字字符组合成一个有效字符,它在字母之前按字母顺序排序。

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

  • 文件100.xml
  • 文件10.xml
  • 文件20.xml
  • 文件k100.xml
  • 文件k10.xml
  • 文件-K20。 XML
  • 文件M100.xml
  • 文件M10.xml
  • 文件M20.xml

我可以用ls -1 | sort -n -k 1.6获得无 'k' 或 'M' 正确的...

  • 文件k100.xml
  • 文件k10.xml
  • 文件-K20的那些.XML
  • 文件M100.xml
  • 文件M10.xml
  • 文件M20.xml
  • file-10.xml
  • file-20.xml
  • file-100。XML

我可以使用ls -1 | sort -n -k 1.7得到它没有一个正确的

  • 文件100.xml
  • 文件10.xml
  • 文件20.xml
  • 文件-K10 .xml
  • file-M10.xml
  • file-k20.xml
  • 文件M20.xml
  • 文件k100.xml
  • 文件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

  • 文件10.xml
  • 文件20.xml
  • 文件100.xml
  • 文件k10.xml
  • 文件k20.xml
  • 文件-K100 .XML
  • 文件M10.xml
  • 文件M20.xml
  • 文件M100.x ml

哎!男孩很高兴“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; 
} 

是这么难?有人可以把这个排序,给我一个副本?请?

+8

您可以通过将 数字字段填充为具有前导零的相同长度,而不是 来依靠特定于平台的怪癖来获得所需的排序顺序,从而为自己节省了一些痛苦。只是说'... – 2010-07-24 03:16:49

+2

我会指出,也许Windows的行为可以做99%的时间做你希望它做的事情,但是说99%的时间做每个人都想做的事是不公平的。事实上,我也可以对Windows排序进行相同的投诉,以便对Linux进行排序。 (尽管将此作为_option_进行排序会很好) – 2010-07-24 03:38:57

+3

这里的编程问题是什么?如果您只想对文件名进行排序,http://superuser.com上的某个人可能会提供帮助。 – Gabe 2010-07-24 03:41:32

回答

2

这将是我的第一个想法:

ls -1 | sed 's/\-\([kM]\)\?\([0-9]\{2\}\)\./-\10\2./' | sort | sed 's/0\([0-9]\{2\}\)/\1/' 

基本上我只是用sed垫用零数,然后再使用它事后剥去前导零。

我不知道在Perl中它可能会更快。

+1

这就是我最终做的,基于你的建议。我有这个,因为我需要在ls -1 $ 1 * .xml |中的f最多4位数字sed -r's/- ([kM]?)([0-9] {4})\ ./- \ 10 \ 2. /; S/- ([KM])([0-9] {3})\ ./- \ 100 \ 2 /; S/- ([KM])([0-9] {2})\ ./- \ 1000 \ 2 /; s/- ([kM]?)([0-9] {1})\ ./- \ 10000 \ 2. /'|排序| sed -r's/0 +([1-9])/ \ 1 /'\';我发现这对于这样一个简单的任务来说是完全荒谬的。这是“排序”IMO的一大失败。 – Scott 2010-08-03 05:09:14

15

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

+0

这也适用于具有不同数字大小的数字:'1 2 3 ... 12 13 14 ... 123 124 125 ... 1123 1124 1125 ...' – Amir 2017-10-12 23:10:12

36

尝试 排序--version排序-f

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

-f选项是忽略的情况下(否则,我在这个例子中,将把k和M的顺序错误)。然而,如果这是你的目标 - 它只是字母顺序,我认为排序不会将字母k和M正确解释为数千和数百万。

+1

这对我来说很完美 – 2012-11-05 23:16:02

+5

比选定的答案更好的解决方案...可能不太方便我猜。 '-V'是'--version-sort'的短标志,供参考。 – 2014-03-27 17:54:49