perl 使用〈>将文件读取到数组中,而不向最后一行添加换行符

wrrgggsh  于 2023-05-01  发布在  Perl
关注(0)|答案(1)|浏览(132)

我尝试通过执行my @array = <$filehandle>;使用菱形运算符将文本文件slurp到数组中,但这总是将\n附加到文件的最后一行,无论它是否存在。如果最后一行不在原始文件中,有没有一种简单的方法可以让它不以\n结尾?我尝试过将标量(使用undef $/)转换为标量,并将标量拆分为数组,假设我可以弹出最后一个元素,如果它是空的,则假设最后一行以\n结束,但最后一个元素始终是最后一行,无论它是否有换行符。我本以为拆分“hello\nworld\n”会给予我一个包含3个元素的数组,最后一个元素是空的,但事实并非如此,而且这似乎是一个非常昂贵的方法来摆脱一个悬空的换行符。我不能使用chomp,因为我不知道文件的最后一行是否应该有换行符。
编辑:为了回应Ikegami声称我的前提是假的,我给出了下面的代码和输出,也许我错过了一些东西。文件test2包含“第一行\n第二行”

my $file = 'test2';
my @lines = &slurp($file);
for (@lines) { print "-$_-\n"; }

sub slurp {
my $f = shift;
open(my $fh, '<', $f) or die $!;
my @ary = <$fh>;
return @ary;
}

输出为

-first line
-
-second line
-

当我将test2中的文本更改为'first line\n second line\n'时,它会输出

-first line
-
-second line
-
-
-

我不能否认你发布的代码在我的机器上产生了相同的输出,但这是我在我的机器上得到的,很明显第二行后有一个换行符。
更新:似乎换行符是由vim添加的,而不是perl。

afdcj2ne

afdcj2ne1#

  • 如果最后一行不在原始文件中,是否有一种简单的方法,可以避免最后一行以\n结尾?*

您提供的代码已经做到了这一点。

  • 这总是将\n附加到文件的最后一行 *

<>不会添加任何内容。

$ printf 'a\nb\nc\n' |
    perl -MData::Dumper -e'$Data::Dumper::Useqq = 1; print( Dumper( [ <> ] ) );'
$VAR1 = [
          "a\n",
          "b\n",
          "c\n"
        ];

$ printf 'a\nb\nc' |
    perl -MData::Dumper -e'$Data::Dumper::Useqq = 1; print( Dumper( [ <> ] ) );'
$VAR1 = [
          "a\n",
          "b\n",
          "c"
        ];

你的说法根本不真实。

  • 我呈现以下代码和输出 *

它并不输出你声称它所做的。

$ cat >a.pl
my $file = 'test2';
my @lines = &slurp($file);
for (@lines) { print "-$_-\n"; }

sub slurp {
my $f = shift;
open(my $fh, '<', $f) or die $!;
my @ary = <$fh>;
return @ary;
}

$ printf 'first line\nsecond line\n' >test2

$ perl a.pl
-first line
-
-second line
-

$ printf 'first line\nsecond line' >test2

$ perl a.pl
-first line
-
-second line-

我假设拆分“hello\nworld\n”会给予一个3个元素的数组
如果你用

split( /\n/, "hello\nworld\n", -1 )   # "hello", "world", ""
  • 我不能用咀嚼 *

chomp即使缺少最后的LF也能正常工作。

  • 我可以弹出最后一个元素如果是空白 *

您是否要求以下内容?

my $file = do { local $/; <> };
my @lines = split( /\n/, $file, -1 );
pop( @lines ) if @lines && $lines[-1] eq "";

可以简化为

my $file = do { local $/; <> };
my @lines = split( /\n/, $file );

甚至

chomp( my @lines = <> );

给定一个行数组(例如<>返回的行),可以使用以下方法检查最后一行是否以LF结尾:

my $has_final_lf = @lines ? substr( $lines[-1], -1 ) eq "\n" : 1;

你没要求这样,但也许这就是你想要的?

相关问题