找出文件的行是否已排序

Tom*_*han 7 command-line text-processing

我有一个很大的文本文件,其中每一行由三个数字组成,除了一些以主题标签 ( #)开头的注释行。我想验证非注释行是否按数字排序。有没有好的方法可以做到这一点?

我假设我必须使用类似的东西提取所有非注释行grep -ve \#- 但是我在哪里可以通过管道来验证输出是否已排序?

注意:不是在寻找对文件进行排序的方法,而是要验证它是否已经排序(以验证我的程序的输出)。不幸的是,这并不像想要对文件的内容进行排序,或者(甚至更多)想要以特定顺序(例如,按字母顺序或按大小)列出文件夹的内容那么常见,因此 Google 有非常对我来说很少...

说明:文件中的数字是真实的,通常是指数形式。我希望它们按数字顺序排序,例如这意味着0.11000E+02 > 0.90000E+01 > 0.15000E-01.

如果它简化了任何,我知道如果文件与我想要的匹配,如果成对计算,前两列将被排序 - 换句话说,如果文件有效,则根本不必考虑第三列。

正式地,你可以这样表达:如果 x1y1是一行的前两个数字,x2并且y2是另一行的前两个数字,那么(x1,y1)>(x2,y2) iff (x1>x2) || (x1==x2 && y1>y2)(x1,y1)>(x2,y2)这里意味着带有x1和的行y1应该被认为更大,带有x2y2,的行(x1,y1)应该出现在文件的下方 (x2,y2)

示例输入: pastebin
我希望将上述文件视为已排序,但如果切换任意两行(不是注释行),则文件不再排序。请注意,行可以有前导空格。

mar*_*elo 5

我最近遇到了这个问题,我使用了 bash 中的 sort --c。这只会检查第一个未排序元素的存在并报告它。它可以与其他标志结合来决定要检查的排序类型(例如数字或字母)


Bas*_*lvi 2

#!/usr/bin/perl -w
use strict;

unless ( @ARGV == 1 && -f -r $ARGV[0] ) {
    die "Expected single file argument!\n";
}

my %cols;
my $ind = 0;

while (<>) {
    chomp;
    next if /^\s*($|#)/;
    ( @{ $cols{col1} }[$ind], @{ $cols{col2} }[$ind], @{ $cols{col3} }[$ind] ) = split;
    $ind++;
}

my @sorted1 = map { ${ $cols{col1} }[$_] } sort {
    ${ $cols{col1} }[$a] <=> ${ $cols{col1} }[$b] or
    ${ $cols{col2} }[$a] <=> ${ $cols{col2} }[$b] or
    ${ $cols{col3} }[$a] <=> ${ $cols{col3} }[$b]
} keys @{ $cols{col1} };
my @sorted2 = map { ${ $cols{col2} }[$_] } sort {
    ${ $cols{col1} }[$a] <=> ${ $cols{col1} }[$b] or
    ${ $cols{col2} }[$a] <=> ${ $cols{col2} }[$b] or
    ${ $cols{col3} }[$a] <=> ${ $cols{col3} }[$b]
} keys @{ $cols{col2} };

if ( "@sorted1" eq "@{ $cols{col1} }" and "@sorted2" eq "@{ $cols{col2} }") {
    print "File is sorted!\n"
}
else { print "File is unsorted!\n" };
__END__
Run Code Online (Sandbox Code Playgroud)

如果列是:

X1 Y1 Z1  
X2 Y2 Z2
Run Code Online (Sandbox Code Playgroud)

排序将是:

如果 (x1 > x2) 那么X1 Y1 Z1>X2 Y2 Z2
如果 (X1 == X2) && (Y1 > Y2) 那么X1 Y1 Z1>X2 Y2 Z2

要将更多列添加到排序顺序中,请复制前两列的模式。我希望这就是你所要求的。