Как работать с Record Separator в Perl - PullRequest
4 голосов
/ 19 ноября 2010

У меня есть данные, которые выглядят так

--
read50_1: read1391364_2,read3529226_1,
--
read46_2: read916_1,read178252_2,read1336397_1,read1824459_2,
read916_1: read0_1
--
read34_1: read209771_2,
--
read32_2: read520377_2,

Я хочу получить доступ к записи, исключая разделитель записей "-".

Но почему этот код не делает этого?

my  $INFILE_file_name = "myfile.txt";      # input file name
my $content = '';
open ( INFILE, '<', $INFILE_file_name )
    or croak "$0 : failed to open input file $INFILE_file_name : $!\n";

{
    local $/ = "--";

    $content = <INFILE>;
    print "$content\n";

}

close ( INFILE );           # close input file

Ответы [ 7 ]

3 голосов
/ 19 ноября 2010

Прежде всего, я предполагаю, что вы имели в виду

local $/ = "--\n"; # or maybe "\n--\n"

(Если вы используете "\n--\n", то первая строка больше не будет считаться разделителем записей, но будет частьюпервая запись. Возможно, вы захотите прочитать эту первую -- строку до изменения $/.)

Помните, что $/ не удаляется <IN> оператор.Для этого используйте chomp.

Во-вторых, файл начинается с разделителя записей, поэтому первая запись будет пустой.

{
    local $/ = "--\n";

    while ($content = <INFILE>) {
      chomp $content;
      print "$content\n" if $content; # Skip empty records
    }
}
2 голосов
/ 19 ноября 2010

Хотя использование разделителя записей здесь возможно, это не очень хорошее решение, если «-» не подразумевает какую-либо значимую группировку данных (которая будет использоваться). Если цель состоит в том, чтобы просто отфильтровать '-', используйте управление циклом.

use strict;
use warnings;

my $file = 'myFile.txt';

open my $fh, '<', $file or die "Unable to open $file: $!";

while ( <$fh> ) {   # Read text file line-by-line

    next if /^--/;  # Skips current line if it begins with '--'
    print;          # Will only execute if line doesn't begin with '--'
}

close $fh;
2 голосов
/ 19 ноября 2010

Вы также можете просто сделать:

while(<INFILE>) {
        print unless(/\s*--\s*/);
}
2 голосов
/ 19 ноября 2010
#!/usr/bin/env perl

use Modern::Perl;
use autodie;
use Data::Dump 'pp';

open my $file, "<", "input.txt";
{
    local $/ = "--\n";
    say pp <$file>;
}
close $file;

И вывод:

(
  "--\n",
  "read50_1: read1391364_2,read3529226_1,\n--\n",
  "read46_2: read916_1,read178252_2,read1336397_1,read1824459_2,\nread916_1: read0_1\n--\n",
  "read34_1: read209771_2,\n--\n",
  "read32_2: read520377_2,\n",
)

Другими словами, чтение не снимает разделитель входной записи.Возможно, вы захотите что-то вроде этого:

open my $file, "<", "input.txt";
{
    local $/ = "--\n";
    for (<$file>) {
        chomp;
        s/\n//g;
        say "<$_>";
    }
}
close $file;

Что дает:

<>
<read50_1: read1391364_2,read3529226_1,>
<read46_2: read916_1,read178252_2,read1336397_1,read1824459_2,read916_1: read0_1>
<read34_1: read209771_2,>
<read32_2: read520377_2,>

В качестве примечания, вы должны использовать открывание с тремя арками и вас может заинтересовать autodie , чтобы вам не пришлось писать шаблон or die.

1 голос
/ 19 ноября 2010

local $ / = "- \ n"; в то время как (чавкать ($ _ =)) {печать}

1 голос
/ 19 ноября 2010

$content = <INFILE> выбирает только следующую строку, которая заканчивается символами в $/. Он должен быть заключен в цикл, чтобы получить все строки.

while ( $content = <INFILE> ) {
    chomp $content;
    print "$content\n";
}

Современные пользователи Perl держатся подальше от файловых дескрипторов голых слов. Вместо этого используйте лексические переменные в качестве файловых дескрипторов. Чтобы узнать, почему лексические переменные предпочтительнее файловых дескрипторов без слов, прочитайте: Файловые дескрипторы заглавных букв .

1 голос
/ 19 ноября 2010

Попробуйте это:

my  $INFILE_file_name = "myfile.txt";
my @content = ( );
open ( INFILE, '<', $INFILE_file_name );
@content = <INFILE>;
close ( INFILE );

foreach my $line (@content) {
    $line =~ s/^\s+//;
    $line =~ s/\s+$//;
    if ($line eq '--') {
        next;
    }
    print $line . "\n";
}

После этого вы сможете получать доступ к записям построчно, без разделителя --. Кроме того, если вы хотите просто поместить его в одну переменную вместо массива, вы можете просто:

$file .= $line . "\n";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...