【问题标题】:How to read line by line a CR-only file with Perl?如何使用 Perl 逐行读取仅限 CR 的文件?
【发布时间】:2011-03-02 08:59:41
【问题描述】:

我正在尝试读取一个只有 CR 作为行分隔符的文件。我正在使用 Mac OS X 和 Perl v.5.8.8。此脚本应在每个平台上运行,适用于每种类型的行分隔符(CR、LF、CRLF)。

我当前的代码如下:

open(FILE, "test.txt");

while($record = <FILE>){
    print $record;
}

close(TEST);

这目前只打印最后一行(或最差)。到底是怎么回事? 显然,我不想转换文件。有可能吗?

【问题讨论】:

  • 我会很烦人,建议您使用strictwarnings 编译指示,它们可以节省您数小时的调试时间。此外,最好使用带有词法文件句柄的现代 3 参数形式的 open。请参阅stackoverflow.com/questions/1479741/… 了解更多信息。

标签: perl line-breaks carriage-return readfile linefeed


【解决方案1】:

您可以使用特殊变量$/设置分隔符:

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;

您不应该对非常大的文件执行此操作,因为文件已完全读入内存。请注意,将 $/ 设置为未定义的值会禁用行分隔符,这意味着读取所有内容直到文件末尾。

【讨论】:

  • "\r" 只是 CR 的一个示例,您可能想分别为 CRLF 和 LF 尝试 "\r\n" 和 "\n"。
  • 哦,我明白了。 CR 和 Terminal 配合得不好。
  • 您的拆分有错误。 Perl 将交替使用第一个匹配的分支,如果它不能满足完整的模式,则只尝试后面的分支。所以如果$content"a\r\nb",那么行的结果就是('a', '', 'b')。重新排列替换为/\r\n|\r|\n/ 将产生期望的结果,可以进一步简化为/\r\n?|\n/
  • 你说得对,我修好了。我通常只使用 /\r?\n/,但这不适用于 CR 换行符。但是,我以前从未见过在实践中使用过仅限 CR 的换行符。
  • 请参阅my answer here 以了解使用\R 分割3 个换行符中的任何一个的替代方法。 (是的,不幸的是,在 CR 被弃用 20 年后仍有使用 CR 的 Mac 程序)
【解决方案2】:

我解决了一个在这里可能有用的更普遍的问题:

如何使用任何行分隔符 (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;
}

【讨论】:

    猜你喜欢
    • 2014-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-08
    • 1970-01-01
    • 1970-01-01
    • 2013-12-26
    相关资源
    最近更新 更多