-4

为什么将 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

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

$/ = "__Data__\n";

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

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

我得到了不受欢迎的输出:

__Data__

而不是理想的输出:

1aaaaaaaaaaa
1bbbbbbbbbbb
1ccccccccccc

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

4

2 回答 2

5

如果我正确理解了这个问题,你想去掉这__Data__部分。你要这个...

1aaaaaaaaaa
1bbbbbbbbbb
1cccccccccc

......但你得到这个......

__Data__
1aaaaaaaaaa
1bbbbbbbbbb
1cccccccccc

您可以使用该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;
    }
}

顺便说一句,因为您更改了“行尾”的概念,__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";
    }
}

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

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

而且我已经打开了严格和警告,这将捕获拼写错误和小错误,例如close(<READLINE>).

于 2013-05-17T21:49:37.193 回答
2

输入.txt

__Data__
1aaaaaaaaaa
aaaaaaaaaaa
aaaaaaaaaaaaa
__Data__
1bbbbbbbbbb
bbbbbbbbbbb
bbbbbbbbbbbbb
__Data__
1cccccccccc
ccccccccccc
ccccccccccccc
__Data__

使用$/=qq{__Data__\n}

perl -e 'use Data::Dumper;$Data::Dumper::Useqq=1; $/=qq{__Data__\n}; open $fh,"input.txt"; print Dumper [ <$fh> ]'

$VAR1 = [
      "__Data__\n",
      "1aaaaaaaaaa\naaaaaaaaaaa\naaaaaaaaaaaaa\n__Data__\n",
      "1bbbbbbbbbb\nbbbbbbbbbbb\nbbbbbbbbbbbbb\n__Data__\n",
      "1cccccccccc\nccccccccccc\nccccccccccccc\n__Data__"
    ];

使用$/=qq{Data}

$VAR1 = [
      "__Data",
      "__\n1aaaaaaaaaa\naaaaaaaaaaa\naaaaaaaaaaaaa\n__Data",
      "__\n1bbbbbbbbbb\nbbbbbbbbbbb\nbbbbbbbbbbbbb\n__Data",
      "__\n1cccccccccc\nccccccccccc\nccccccccccccc\n__Data",
      "__"
    ];

我想这是不言自明的。

于 2013-05-18T06:32:46.470 回答