如何在Perl中使用记录分隔符

时间:2010-11-19 06:55:45

标签: linux perl unix

我有一个看起来像这样的数据

--
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 个答案:

答案 0 :(得分:3)

首先,我猜你的意思是

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

(如果您使用"\n--\n",则第一行将不再被视为记录分隔符,但将成为第一条记录的一部分。您可能希望读取第一行--行< em>在更改$/之前。)

请注意<IN>运算符未删除$/。使用chomp来执行此操作。

其次,文件以记录分隔符开头,因此第一条记录将为空白。

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

    while ($content = <INFILE>) {
      chomp $content;
      print "$content\n" if $content; # Skip empty records
    }
}

答案 1 :(得分:2)

#!/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,>

作为旁注,您应该use the three-arg open并且您可能对autodie感兴趣,这样您就不必编写or die样板了。

答案 2 :(得分:2)

您也可以这样做:

while(<INFILE>) {
        print unless(/\s*--\s*/);
}

答案 3 :(得分:2)

虽然在这里使用记录分隔符是可能的,但它不是一个非常好的解决方案,除非' - '暗示一些有意义的数据分组(将被使用)。如果目的只是过滤掉' - ',请使用循环控制。

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;

答案 4 :(得分:1)

试试这个:

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";

答案 5 :(得分:1)

$content = <INFILE>仅提取以$/中的字符结尾的下一行。它应该被包裹在循环中以获得所有的行。

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

Modern Perl用户远离裸字文件句柄。相反,使用词法变量作为文件句柄。要知道为什么词汇变量比bareword文件句柄更受欢迎,请阅读:Bareword uppercase filehandles

答案 6 :(得分:1)

local $ / =“ - \ n”; 而(格格($ _ =)){打印;}