Perl сызықтары бойынша сұрыптау

Менде келесідей файл бар:

text text text text : 6 min
text text text text : 2 min
text text text text : 8 min
text text text text : 2 min

Бұл файлды алу үшін осы файлды сұрыптау керек:

text text text text : 2 min
text text text text : 2 min
text text text text : 6 min
text text text text : 8 min

Мен мұны істеуге тырыстым, бірақ ол жұмыс істемейді:

my @copy = ();
open (INFILE, $ARGV[0]);
while () {
push (@copy, $_);
}
my @lines = sort grep /^: (\d+) min/ , @copy;
print @lines;

Perl-да мұны жеңіл тәсілі бар ма?

3

6 жауаптар

sort арқылы оңайырақ:

$ sort -t: -k2 file
text text text text : 2 min
text text text text : 2 min
text text text text : 6 min
text text text text : 8 min
  • -t: means "set the delimiter of columns as :"
  • -k2 means "filter on 2nd column", that is, just after the :.
8
қосылды
Не айтқың келеді? sort қолданатын ОР ... oh, сіз басқа sort дегенді білдіреді ...
қосылды автор doubleDown, көзі

Ең алдымен, sort шешімін ұсынған болармын, себебі ол қарапайым болып көрінеді. Дегенмен, Perl нұсқасы. Ол Schwartzian түрлендіруіне негізделген . Бұл талап етілмейді, бірақ кез-келген ірі файлдар үшін бұл тиімдірек, және ол біршама қарапайым көрінеді.

use strict;
use warnings;

my @lines = <>;    # read the input file
@lines = map $_->[1],
         sort { $a->[0] <=> $b->[0] }
         map { my ($num) = /:\s*(\d+)/; [ $num, $_ ] } @lines;
print @lines;

Негізгі идея мынада:

  • Start with a map statement to extract the numbers, return a reference to a two-element array that contains that number, and the original line [ $num, $_ ]
  • Sort the resulting list based on the first element.
  • End with another map statement that turns our arrays back into the original lines.
4
қосылды

Егер ол Perl (fedorquis ұсынысы өте жақсы) болуы керек болса, онда бұл ноград керек:

my @file=<>;
foreach (sort {(split(' ',$a))[5] <=> (split(' ',$b))[5]} @file) {print;}

Файл атауын параметр ретінде беріңіз.

1
қосылды
Сондай-ақ жұмыс істейді. Мен тек дәстүрлі адаммын :)
қосылды автор 0xCAFEBABE, көзі
Бірінші бөлімде келісілді және тиісінше өзгерді. Мен квантитерге мұқият келіспеймін, бірақ ОП-да сипатталмаған әйгілендірілген жағдайлар туралы айтып жатқанда, мен өздігінен квалификациялық мәселе бойынша өзімді қорғамаймын.
қосылды автор 0xCAFEBABE, көзі
/\ s/ емес, бөлуге арналған әдепкі '' пайдалануыңыз қажет. /\ s +/ параметрін таңдауға арналған жалғыз себеп - бұл бос кеңістіктің жоғалтқанын қаламасаңыз. Сондай-ақ, сізде + кодының жетіспейтінін ескеріңіз, егер кіріс мәтіні жүйелі бос кеңістік болса, ол бір-бірден қате жібереді.
қосылды автор TLP, көзі
5 орнына -2 туралы не айтасыз?
қосылды автор devnull, көзі

Тіркелгіңіз дұрыс емес. Қалайсың:

/[^:]+: (\d+) min/

Сондай-ақ, мұны сіз жасай алмайсыз ба?

@copy = ;
1
қосылды

Ұқсас сандардың негізінде сызықтарды сұрыптау үшін Schwartzian түрлендіруін пайдалануға болады

use strict;
use Data::Dumper;

my @lines = ("Test:2 min","Test:8 min","Test:6 min");
print Dumper(\@lines);

@lines = map { $_->[0] }
    sort { $a->[1] <=> $b->[1] }
    map { [$_, /(\d+) min/] } @lines;

@lines = sort @lines;
print Dumper(\@lines);

Шығару:

$VAR1 = [
          'Test:2 min',
          'Test:8 min',
          'Test:6 min'
        ];
$VAR1 = [
          'Test:2 min',
          'Test:6 min',
          'Test:8 min'
        ];
0
қосылды

my @lines = map { $_->[1] } sort { $a->[0] <=> $b->[0]} map { [ /:\s(\d+)/, $_ ] } @copy

Бұл қалай жұмыс істейді

оң жақтан бастап, алғашқы карта массив массивтерін жасайды. Әрбір массивтің элементі әр элементтің бірінші элементі және екінші элемент ретінде бүкіл жол ретінде шығарылған саннан тұрады

Содан кейін сұрыптау массивтің бірінші элементінде сандық салыстыру үшін Ufo операторы арқылы орнатылады

Ақырында, соңғы карта тек екінші элементтерді ғана алады, енді олар дұрыс тәртіпте

Бұл әдіс «Schwartzian Transform» деп аталады және perldoc perlfaq4 бөлімінде орналасқан «Массивті (anything) қалай сұрыптауға болады?»

0
қосылды