1

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

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

我想确定它的一列或多列是否已排序。

有什么快速的方法吗?也许使用 Perl 或一些 unix 命令?或者类似的东西?

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

4

4 回答 4

9

只需使用-c选项sort来检查排序顺序并-k指定在哪一列:

$ sort -c -k2,2 file
sort: file:2: disorder: Col2: Date-time (yy-mm-yyyy 0000000000)

或者-C抑制输出并测试退出代码。您可能还想根据数据指定排序类型,例如版本排序-n的数字排序等。-v

于 2013-01-15T16:06:06.727 回答
4

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

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

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

于 2013-01-15T16:09:10.653 回答
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
于 2013-01-15T15:59:29.100 回答
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";
}

测试文件.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 循环。

于 2013-01-15T16:18:49.280 回答