perl: как отсортировать строки в файле в зависимости от второго поля и обновить тот же файл - PullRequest
0 голосов
/ 03 августа 2020

файл: entries.txt

d1 t-waaa.html
a1 t-paaa.html
e1 t-waaa.html
c1 t-uaaa.html
b1 t-paaa.html
f1 t-paaa.html

perl файл check.pl

#! /bin/perl
$cur_file = $ARGV[0];  # here ARGV[0] is entries.txt
open (FILE, "< $cur_file") or die "cannot open file: $!";
@file_lines = <FILE>;

@lines = map $_->[1],
         sort { $a->[1] <=> $b->[1] }
         map { my ($num) = /-\s*(\d+)/; [ $num, $_ ] } @file_lines;

print @lines;

Я не получаю ожидаемого результата. файл печатается как есть.

ожидаемый результат:

a1 t-paaa.html
b1 t-paaa.html
f1 t-paaa.html
c1 t-uaaa.html
d1 t-waaa.html
e1 t-waaa.html

где код ошибся, я не уверен.

Ответы [ 3 ]

4 голосов
/ 03 августа 2020
  • \d соответствует цифре; вы, вероятно, хотели использовать вместо него \w, \S или [a-z].

  • <=> сравнивает числа; у вас есть не числа для сравнения, а строка. Вместо этого используйте cmp.

  • Вторые элементы (->[1]) ваших массивов содержат имена файлов, а не поля, которые вы хотите сравнить. Вместо этого используйте ->[0].

В целом, это дает вам:

@lines = map $_->[1],
         sort { $a->[0] cmp $b->[0] }
         map { my ($num) = /\s+(\S+)/; [ $num, $_ ] } @file_lines;

Обратите внимание, что я заменил -\s* на \s+, так как заголовок в вашем вопросе упоминается, что вы хотите отсортировать в соответствии со вторым полем, которое, похоже, происходит после символа пробела. При необходимости используйте -\s*.

1 голос
/ 04 августа 2020

Вышеуказанный код хорош. вы также можете использовать пакет use List::UtilsBy 'sort_by'; проверьте https://metacpan.org/pod/List :: UtilsBy

use strict;
use warnings;
use List::UtilsBy 'sort_by';
use Data::Printer;

my $cur_file =   "entries.txt";
open (FILE, "< $cur_file") or die "cannot open file: $!";
my @file_lines = <FILE>;
close(FILE);

my @lines = sort_by { (split(' ', $_))[1] } @file_lines;
p @lines;

Вывод

perl sort.pl
[
    [0] "a1 t-paaa.html
",
    [1] "b1 t-paaa.html
",
    [2] "f1 t-paaa.html",
    [3] "c1 t-uaaa.html
",
    [4] "d1 t-waaa.html
",
    [5] "e1 t-waaa.html
"
]
0 голосов
/ 03 августа 2020

Поскольку это строковое сжатие, ваш код должен выглядеть так:

...
@lines = map $_->[1],
         sort { $a->[1] cmp $b->[1] }
         map { my ($num) = /-\s*(\d+)/; [ $num, $_ ] } @file_lines;
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...