如何确定大型文本文件中的一个或多个列是否已排序或未排序

时间:2013-01-15 15:53:08

标签: perl bash unix cmd

我有超过1GB的大文本文件。该文件有4个由TAB分隔的列。

Col1: Guid
Col2: Date-time (yy-mm-yyyy 0000000000)
Col3: String
Col4: String

我想确定其列中的一个或多个是否已排序。

有没有快速的方法呢?也许使用Perl或一些unix命令?或类似的东西?

我在大型服务器和本地Windows机器上都有文件,因此内存或CPU速度或操作系统不是问题。

4 个答案:

答案 0 :(得分:9)

只需使用-c的{​​{1}}选项检查排序顺序,并使用sort指定哪一列:

-k

$ sort -c -k2,2 file sort: file:2: disorder: Col2: Date-time (yy-mm-yyyy 0000000000) 抑制输出并测试退出代码。您可能还需要根据-C等数据指定排序类型,以便对版本排序等进行数字排序-n

答案 1 :(得分:4)

许多版本的sort都可以选择检查文件是否已排序。例如,使用笔记本电脑上的版本(Debian),我可以这样做:

if sort -C -k 2,2 somefile
then
  # something
else
  # something else
fi

检查文件的第二列是否已排序。退出代码sort表示成功或失败。

答案 2 :(得分:3)

首先确定列 然后使用awk

awk '{print $2}' OFS="\t" test.tmp > unsorted_file.dat

第二栏

awk '{print $2}' OFS="\t" test.tmp | sort > sorted_file.dat

diff sorted_file.dat unsorted_file.dat

答案 3 :(得分:1)

只需将该行拆分为列,然后将它们与上一行中的值进行比较。如果前一个值大于当前行中的值,则不对该列进行排序。

#! /usr/bin/perl

use strict;
use warnings;

my @sorted = (1, 1, 1, 1);
my $first = <>; # read the first line
my @prev = split(/\t/, $first);

while (<>) {
    my @cols = split(/\t/);
    for (my $i = 0; $i < 4; ++$i) {
        $sorted[$i] = 0 if ($prev[$i] gt $cols[$i]);
    }

    @prev = @cols;
}

for (my $i = 0; $i < 4; ++$i) {
    my $not = $sorted[$i] ? '' : 'not ';
    print "Column $i is $not sorted\n";
}

测试file.txt

a   a   a   a
b   b   b   b
c   c   c   c
d   d   d   d
e   e   e   a
f   d   f   f
g   g   g   g

呼叫

perl script.pl file.txt

会给你

  

第0列分类为
  第1列未分类
  第2列分类为   第3列未排序

这是文本比较和升序测试。如果您需要其他订单或不同的比较,则必须相应调整内部for循环。