为什么将Perl输入记录分隔符设置为$ / =“ __ Data __ \ n”不起作用?

Yet*_*ene -4 perl

为什么将Perl输入记录分隔符设置为$ / =“ __Data __ \ n”不起作用?

数据记录设置如下:

 __Data__\n
 1aaaaaaaaaa\n
 aaaaaaaaaaa\n
 aaaaaaaaaaaaa\n
 __Data__\n
 1bbbbbbbbbb\n
 bbbbbbbbbbb\n
 bbbbbbbbbbbbb\n
 __Data__\n
 1cccccccccc\n
 ccccccccccc\n
 ccccccccccccc\n
 __Data__\n
Run Code Online (Sandbox Code Playgroud)

这是访问每个数据记录第一行的Perl代码...

$/ = "__Data__\n";

open READFILE, "<", "logA.txt" or die "Unable to open file";

while (<READFILE>)
{
   if (/([^\n]*)\n(.*)/sm)
   {
       print "$1\n";
   }
}
close(<READFILE>);
Run Code Online (Sandbox Code Playgroud)

我得到以下不良输出:

__Data__
Run Code Online (Sandbox Code Playgroud)

而不是以下内容的理想输出:

1aaaaaaaaaaa
1bbbbbbbbbbb
1ccccccccccc
Run Code Online (Sandbox Code Playgroud)

为什么输入记录分隔符$/="__Data__";不起作用?应该如何运作?

Sch*_*ern 5

如果我对问题的理解正确,那么您想去除__Data__零件。你要这个...

1aaaaaaaaaa
1bbbbbbbbbb
1cccccccccc
Run Code Online (Sandbox Code Playgroud)

...但是你得到了...

__Data__
1aaaaaaaaaa
1bbbbbbbbbb
1cccccccccc
Run Code Online (Sandbox Code Playgroud)

您可以使用chomp命令删除行尾。通常,这只是换行符,但是会chomp响应您设置$/的内容。

use strict;
use warnings;

{
    local $/="__Data__\n";
    open my $fh, "<", "logA.txt" or die "Unable to open file";

    while(my $record = <$fh>) {
        chomp $record;
        print $record;
    }
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,因为您更改了“行尾”的概念,所以__Data__字段之间的所有内容都将视为一行。如果需要分割线,可以使用my @lines = split "\n", $record

use strict;
use warnings;

{
    # Isolate the change to the global $/
    local $/="__Data__\n";

    open my $fh, "<", "logA.txt" or die "Unable to open file";

    while(my $record = <$fh>) {
        # Remove the __Data__ separator
        chomp $record;

        # Split the record by line
        my @lines = split /\n/, $record;

        # Empty record, skip it
        next if !@lines;

        # Print the first line of the record
        print $lines[0], "\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

我还对您的代码进行了一些常规改进。 $/是全局的,将影响读取文件的所有内容。 local确保您的更改仅发生在块内。

我使用了词法文件句柄,当它们超出范围时(当声明它们的块完成时)它们会自动关闭。

而且我已经启用了严格的警告来捕捉错别字和小错误close(<READLINE>)