在Perl中,我如何;“咕噜”;将多个文件的内容转换为字符串?

在Perl中,我如何;“咕噜”;将多个文件的内容转换为字符串?,perl,Perl,Perl有很多方便的习惯用法,可以轻松完成常见的事情,包括: 文件读取操作符,如果在没有文件句柄的情况下使用,将无缝地打开并读取@ARGV中的所有文件,一次一行: while (<>) { print $., $_; } 但这两个习惯用法并没有像我预期的那样协同工作:在我重置$/之后,在文件末尾停止使用的声音:下面只给出了第一个文件的内容 local $/; $content = <>; local$/$内容=; 现在,我相信这种行为一定是故意的,但我真的不在乎

Perl有很多方便的习惯用法,可以轻松完成常见的事情,包括:

  • 文件读取操作符
    ,如果在没有文件句柄的情况下使用,将无缝地打开并读取
    @ARGV
    中的所有文件,一次一行:

    while (<>) { print $., $_;  }
    
  • 但这两个习惯用法并没有像我预期的那样协同工作:在我重置
    $/
    之后,在文件末尾停止使用
    的声音:下面只给出了第一个文件的内容

    local $/; $content = <>;
    
    local$/$内容=;
    

    现在,我相信这种行为一定是故意的,但我真的不在乎。将所有文件的所有内容提取到字符串中的简明Perl习惯用法是什么?(相关问题提到了一种将文件列表拼凑成单独字符串的方法,这是一个开始……但如果您以后还需要连接字符串,就不那么优雅了。)

    您意识到您只隐藏了多个
    打开的调用,对吗?没有什么神奇的方法可以不逐个打开所有文件就读取多个文件

    正如您所发现的,如果
    $/
    设置为
    undef

    处理
    的内部机制会在打开
    @ARGV
    时从中删除每个文件名,因此我建议您只需在
    时使用
    循环,该循环使用
    读取,直到
    @ARGV
    为空

    看起来是这样的

    use strict;
    use warnings 'all';
    
    my $data;
    {
        local $/;
        $data .= <> while @ARGV;
    }
    
    使用严格;
    使用“全部”警告;
    我的$数据;
    {
    本地$/;
    $data.=while@ARGV;
    }
    
    因为似乎没有一种方法可以一次吞咽所有东西,一个紧凑的解决方案是将
    放在列表上下文中。隐式重复调用将获取所有内容

    local $/;
    $data = join "", <>;
    
    local$/;
    $data=加入“”;
    
    这会将所有文件的内容保存在一个列表中,直到它们都被读取,然后再将它们复制到
    $data
    并丢弃单个字符串,因此首先更改
    $/
    没有什么意义。如果只有几个文件,这是可以的,但是如果有很多文件(例如,通过提供通配符模式作为命令行参数),那么这是浪费。Perl在列表上下文中没有迭代器行为?我本以为
    会被
    连接
    ,这在最坏的情况下相当于答案中的显式循环(而且可能更好,因为字符串是内部连接的。)Perl中没有隐藏的迭代器行为,只是因为Python(有时)会这样做,所以它的方式并不正确。很有可能编写一个迭代的
    readline
    join
    ,按照您所描述的方式执行,但是结果会比反复使用
    =
    更神秘,更慢。Perl哲学非常注重透明度,因此只有像排序算法这样的东西才是黑盒的。我从Perl中学到了我所知道的关于面向对象编程的一切,正是因为它是完全自组装的,而且它是我作为教学语言的第一选择。我想这取决于你的学生是谁。我的学生(人文学科)需要知道如何驾驶汽车,而不是如何将汽车拆开再组装起来。我认为“迭代连接”本身就太窄了。如果“在列表上下文中”的意思是在作为参数传递之前构造整个列表,那么它就是这样。我确实是在外推python概念(以一种非常不同的方式“透明”),我只是在胡思乱想。perl中一个局部变量可以保存多少数据?有内存限制吗?@Arijit:单个标量可以容纳进程所能分配的内存,Perl标量数据结构以及Perl解释器、编译程序和任何其他数据都会有一些开销。2GB的字符串是完全可行的。显然,64位构建的perl将能够处理比32位构建多得多的内存。Thank@borodin——如果文件大小超出处理器的处理能力,将会发生什么情况。是停止还是跳过额外的内存?这到底是为了什么?如果你感兴趣的话,我想你需要问一个适当的问题。如果Perl无法分配它所需的内存,那么它将以非零退出代码和消息“内存不足”而死亡。但您确实应该以较小的单位读取文件,通常是一行。如果您认为需要在内存中保存整个文件,那么您的设计可能是wrong@Borodin是的,我知道涉及多个
    打开的
    s。。这就是我所说的“无缝”:它发生了,但我不必握住它的手,甚至不必看它如果您不介意将文件提取到数组中(不需要连接或字符串连接)。的可能重复。您如何确保此问题不重复?@PeterMortensen,它不重复。将每个文件拼成一个单独的字符串,然后需要将其连接在一起。如果没有更好的解决方案(这实际上就是我在自我回答中所做的),那就必须这样做,但如果不问这个问题,我就无法知道这一点。@СССаа27,如果可以避免的话,我宁愿不要将每个文件提取到不同的字符串中。它们需要加入或以其他方式进行后处理。这对读取多个指定为命令行参数的文件有何帮助<知道代码>文件::Slurp
    很好,但它不能回答问题。
    local $/;
    $data = join "", <>;
    
    use File::Slurp qw/read_file/;
    my $text = read_file( 'filename' ) ;