Узнайте, отсортированы ли строки файла

У меня большой текстовый файл, где каждая строка состоит из трех чисел, за исключением нескольких строк комментариев, которые начинаются с хэштега (#). Я хочу убедиться, что строки без комментариев отсортированы по номерам. Есть ли хороший способ сделать это?

Я предполагаю, что мне нужно извлечь все строки без комментариев с чем-то вроде grep -ve \# - но куда мне направить это, чтобы убедиться, что выходные данные отсортированы?

Примечание: Я не ищу способ сортировки файла, а скорее чтобы убедиться, что он уже отсортирован (чтобы проверить вывод моей программы). К сожалению, это не так часто, как желание сортировать содержимое файла, или (даже более того) желание перечислить содержимое папки в определенном порядке (например, в алфавитном порядке или по размеру), поэтому у Google очень мало для меня ...

Пояснение: Числа в файле действительные, обычно в экспоненциальной форме. Я хочу, чтобы они были отсортированы в числовом порядке , что, например, означает, что 0.11000E+02 > 0.90000E+01 > 0.15000E-01.

Если это упрощает, я знаю, что если файл соответствует тому, что я хочу, первые два столбца будут отсортированы, если они подсчитаны попарно - другими словами, если файл действителен, третий столбец не должен рассматриваться на всех.

Формально вы можете выразить это следующим образом: если x1 и y1 - первые два числа в одной строке, а x2 и y2 - первые два числа в другой строке, то (x1,y1)>(x2,y2) тогда и только тогда (x1>x2) || (x1==x2 && y1>y2). (x1,y1)>(x2,y2) здесь означает, что линия с x1 и y1 должна считаться более крупной, линия с x2 и y2 и (x1,y1) должна появиться ниже (x2,y2) в файл.

Пример ввода: pastebin
Я ожидаю, что указанный выше файл будет считаться отсортированным, но если какие-либо две строки (не являющиеся строками комментариев) переключаются , файл больше не сортируется. Обратите внимание, что строки могут иметь начальные пробелы.

7
задан 17 August 2018 в 13:59

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__

Если столбцы:

X1 Y1 Z1  
X2 Y2 Z2

Вид будет:

если (x1> x2) затем X1 Y1 Z1 > X2 Y2 Z2
если (X1 == X2) && (Y1> Y2) затем X1 Y1 Z1 > X2 Y2 Z2

Для добавления большего количества столбцов в порядок сортировки скопируйте шаблон для первых двух. Я надеюсь, что это - то, что Вы попросили.

2
ответ дан 17 August 2018 в 13:59

У меня недавно был этот вопрос, и я использовал sort -c из bash. Это будет только проверять наличие первого несортированного элемента и сообщать о нем и его строке. Его можно комбинировать с другими флагами для определения типа сортировки, который будет проверяться (например, числовой или буквенный).

0
ответ дан 17 August 2018 в 13:59

Другие вопросы по тегам:

Похожие вопросы: