Извлечение определенных данных из текстового файла в Perl - PullRequest
1 голос
/ 02 февраля 2012

Я новичок в Perl и пытаюсь извлечь конкретные данные из файла, который выглядит следующим образом:

 Print of   9 heaviest strained elements:    


   Element no   Max strain 
      20004         9.6 % 
      20013         0.5 % 
      11189         0.1 % 
      20207         0.1 % 
      11157         0.1 % 
      11183         0.0 % 
      10665         0.0 % 
      20182         0.0 % 
      11160         0.0 % 


 ==================================================

Я хотел бы извлечь только номера элементов (20004, 20013 и т. Д.) И записать их в новый файл. Чтение файла должно закончиться, как только будет достигнута строка (=========), так как в файле появятся дополнительные номера элементов с таким же заголовком. Надеюсь, что это имеет смысл. Любой совет высоко ценится!

Теперь у меня есть этот код, который дает мне список чисел, максимум 10 подряд:

my $StrainOut = "PFP_elem"."_$loadComb"."_"."$i";
open DATAOUT, ">$StrainOut" or die "can't open $StrainOut";  # Open the file for writing.

open my $in, '<', "$POSTout" or die "Unable to open file: $!\n";
my $count = 0;

 while(my $line = <$in>) {
  last if $line =~ / ={10}\s*/;
  if ($line =~ /% *$/) {
    my @columns = split "         ", $line;
    $count++;
    if($count % 10 == 0) {
      print DATAOUT "$columns[1]\n";
    }
    else {
      print DATAOUT "$columns[1] ";
    }      
  }
}
close (DATAOUT);
close $in;

Что нужно изменить, так это строка "my @columns = split ...". В настоящий момент он разбивает скалярную строку $ всякий раз, когда у него есть «9 пробелов». Поскольку количество цифр номеров элементов может варьироваться, это плохой способ извлечения данных. Можно ли просто читать слева направо, пропуская все пробелы и записывая числа только до тех пор, пока за числами не последует больше пробелов (таким образом, процентное значение игнорируется)?

Ответы [ 5 ]

1 голос
/ 02 февраля 2012

Однострочник с использованием триггера:

perl -ne '
  if ( m/\A\s*(?i)element\s+no/ .. ($end = /\A\s*=+\s*\Z/) ) {
    printf qq[$1\n] if m/\A\s*(\d+)/;
    exit 0 if $end
  }
' infile

Результат:

20004
20013
11189
20207
11157
11183
10665
20182
11160
1 голос
/ 02 февраля 2012
#!/usr/bin/perl
use strict;
use warnings;

while (<>) {                        # read the file line by line
    if (/% *$/) {                   # if the line ends in a percent sign
        my @columns = split;        # create columns
        print $columns[0], "\n";    # print the first one
    }
    last if /={10}/;                # end of processing
}
0 голосов
/ 02 февраля 2012

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

Вкл * nix:

cat in_file.txt | perl -ne 'print "$1\n" if ( m/\s*(\d+)\s*\d+\.\d+/ )' > out_file.txt

В Windows:

type in_file.txt | perl -ne "print qq{$1\n} if ( m/\s*(\d+)\s*\d+\.\d+/ )" > out_file.txt
0 голосов
/ 02 февраля 2012
#!/usr/bin/perl
use strict;
use warnings;

open my $rh, '<', 'input.txt' or die "Unable to open file: $!\n";
open my $wh, '>', 'output.txt' or die "Unable to open file: $!\n";

while (my $line = <$rh>) {        
    last if $line =~ /^ ={50}/;
    next unless $line =~ /^ {6}(\d+)/;
    print $wh "$1\n";
}

close $wh;
0 голосов
/ 02 февраля 2012
#!/usr/bin/perl
use strict;
use warnings;

while (my $f= shift) {
   open(F, $f) or (warn("While opening $f: $!", next);
   my foundstart=0;
  while(<F>) {
     ($foundstart++, next) if /^\s#Element/;
     last if /\s*=+/;
     print $_ if $foundstart;
  }
  $foundstart=0;
  close(F);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...