извлечь каждый n-й номер - PullRequest
       1

извлечь каждый n-й номер

2 голосов
/ 23 февраля 2011

Я хочу извлечь каждое третье число (42.034, 41.630, 40.158 и т. Д.) Из файла, см. Пример-

42.034  13.749  28.463  41.630  12.627  28.412  40.158  12.173  30.831  26.823
12.596  32.191  26.366  13.332  32.938  25.289  12.810  32.419  23.949  13.329

Есть предложения по использованию сценария perl?

Спасибо, dac

Ответы [ 8 ]

8 голосов
/ 23 февраля 2011

Вы можете разделить содержимое файла на отдельные числа и использовать оператор по модулю , чтобы извлечь каждое третье число:

my $contents = do { local $/; open my $fh, "file" or die $!; <$fh> };    
my @numbers = split /\s+/, $contents;

for (0..$#numbers) {
    $_ % 3 == 0 and print "$numbers[$_]\n";
}
4 голосов
/ 23 февраля 2011
use strict;
use warnings;
use 5.010; ## for say
use List::MoreUtils qw/natatime/;

my @vals = qw/42.034  13.749  28.463  41.630  12.627  28.412  40.158  12.173  30.831 
26.823 12.596  32.191  26.366  13.332  32.938  25.289  12.810  32.419  23.949  13.329/;
my $it = natatime 3, @vals;
say while (($_) = $it->());
2 голосов
/ 24 февраля 2011

Это одна строка!

$ perl -lane 'print for grep {++$i % 3 == 1} @F' /path/to/your/input

-n дает вам построчную обработку, -a автоматическое разделение для обработки поля и $i (фактически инициализируется в ноль для наших целей) ведет подсчет количества обработанных полей ...

2 голосов
/ 23 февраля 2011

Это, вероятно, самый короткий способ указать это.Если @list ваш список чисел

 @list[ grep { $_ % 3 == 0 } 0..$#list ]
1 голос
/ 23 февраля 2011

Этот метод позволяет избежать одновременного чтения всего файла в память:

use strict;

my @queue;

while (<>) {
    push @queue, / ( \d+ (?: \. \d* ) ? ) /gx;
    while (@queue >= 3) {
        my $third = (splice @queue, 0, 3)[2];
        print $third, "\n";  # Or do whatever with it.
    }
}
0 голосов
/ 24 февраля 2011

Полагаю, вы обнаружите, что эта работа в соответствии со спецификацией ведет себя вежливо и никогда не читает больше, чем нужно.

#!/usr/bin/env perl

use 5.010_001;

use strict;
use autodie;
use warnings qw[ FATAL all ];
use open     qw[ :std IO :utf8 ];

END { close STDOUT }

use Regexp::Common;
my $real_num_rx = $RE{num}{real};

my $left_edge_rx = qr{
    (?: (?<= \A              )  # or use \b
      | (?<= \p{White_Space} )  # or use \D
    )
}x;

my $right_edge_rx = qr{
    (?= \z                      # or use \b
      | \p{White_Space}         # or use \D
    )
}x;

my $a_number_rx = $left_edge_rx
                . $real_num_rx
                . $right_edge_rx
                ;

if (-t STDIN && @ARGV == 0) {
    warn "$0: reading numbers from stdin,"
       . " type ^D to end, ^C to kill\n";
}


$/ = " ";
my $count = 0;
while (<>) {
    while (/($a_number_rx)/g) {
        say $1 if $count++ % 3 == 0;
    }
}
0 голосов
/ 23 февраля 2011

Похоже, в этом посте отсутствовало решение, которое не считывало весь файл и использовало grep.

#!/usr/bin/perl -w

use strict;

my $re = qr/-?\d+(?:\.\d*)/; # Insert a more precise regexp here
my $n = 3;

my $count = 0; 
while (<>) {
     my @res = grep { not $count++ % $n } m/($re)/go;
     print "@res\n";
};
0 голосов
/ 23 февраля 2011

Если файл содержит 10 чисел в каждой строке, вы можете использовать это:

perl -pe 's/([\d.]+) [\d.]+ [\d.]+/$1/g;' file

Это не чистое решение, но оно должно "делать работу".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...