我正在尝试读取一个只有 CR 作为行分隔符的文件。我正在使用 Mac OS X 和 Perl v.5.8.8。该脚本应该在每个平台上运行,适用于每种类型的行分隔符(CR、LF、CRLF)。
我当前的代码如下:
open(FILE, "test.txt");
while($record = <FILE>){
print $record;
}
close(TEST);
这目前只打印最后一行(或最差)。到底是怎么回事?显然,我不想转换文件。是否可以?
我正在尝试读取一个只有 CR 作为行分隔符的文件。我正在使用 Mac OS X 和 Perl v.5.8.8。该脚本应该在每个平台上运行,适用于每种类型的行分隔符(CR、LF、CRLF)。
我当前的代码如下:
open(FILE, "test.txt");
while($record = <FILE>){
print $record;
}
close(TEST);
这目前只打印最后一行(或最差)。到底是怎么回事?显然,我不想转换文件。是否可以?
您可以使用特殊变量设置分隔符$/
:
local $/ = "\r" # CR, use "\r\n" for CRLF or "\n" for LF
my $line = <FILE>;
有关详细信息,请参阅perldoc perlvar。
另一种适用于各种换行符的解决方案是一次 slurp 整个文件,然后使用正则表达式将其分成几行:
local $/ = undef;
my $content = <FILE>;
my @lines = split /\r\n|\n|\r/, $content;
但是,您不应该对非常大的文件执行此操作,因为该文件已完全读入内存。请注意,将 $/ 设置为未定义的值会禁用行分隔符,这意味着在文件末尾之前读取所有内容。
我解决了一个在这里可能有用的更普遍的问题:
如何使用任何行分隔符 (CR/CRLF/LF) 逐行解析大文件,但事先未知。
“大”文件意味着不能将整个文件读入一个变量。这里函数 'detectEndOfLine' 获取文件名并返回 '\r' 或 '\n',无论用于行尾(它从文件结尾)。
my $file = "test.txt";
local $/ = detectEndOfLine($file);
open(IN, $file) or die "Can't open file \"$file\" for reading: $!\n";
while(<IN>) {
s/\r\n|\n|\r$//;
print "$_\n";
}
sub detectEndOfLine {
my $file = $_[0];
my $size = -s $file;
print "\"$size\"\n";
open(IN, $file) or die "Can't open file \"$file\" for reading: $!\n";
for(my $i = $size; $i >= 0; --$i) {
seek(IN, $i, 0);
$_ = <IN>;
my $sym = substr($_, 0, 1);
return $sym if( $sym eq "\n" or $sym eq "\r" );
}
return undef;
}