Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 在Perl中,如何将整个文件读入字符串?_String_Perl_Slurp - Fatal编程技术网

String 在Perl中,如何将整个文件读入字符串?

String 在Perl中,如何将整个文件读入字符串?,string,perl,slurp,String,Perl,Slurp,我正在尝试将一个.html文件作为一个大的长字符串打开。这就是我得到的: open(FILE, 'index.html') or die "Can't read file 'filename' [$!]\n"; $document = <FILE>; close (FILE); print $document; open(文件'index.html')或die“无法读取文件'filename'[$!]\n”; $document=; 关闭(文件); 打印$document

我正在尝试将一个.html文件作为一个大的长字符串打开。这就是我得到的:

open(FILE, 'index.html') or die "Can't read file 'filename' [$!]\n";  
$document = <FILE>; 
close (FILE);  
print $document;
open(文件'index.html')或die“无法读取文件'filename'[$!]\n”;
$document=;
关闭(文件);
打印$document;
其结果是:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN
一个简单的方法是:

while (<FILE>) { $document .= $_ }
while(){$document.=$\
另一种方法是更改输入记录分隔符“$/”。您可以在裸块中本地执行此操作,以避免更改全局记录分隔符

{
    open(F, "filename");
    local $/ = undef;
    $d = <F>;
}
{
打开(F,“文件名”);
本地$/=undef;
$d=;
}
添加:

在读取文件句柄之前。看到了吗

$perldoc-q“整个文件” 请参见
perldoc perlvar
和中的

顺便说一句,如果您可以将脚本放在服务器上,您就可以拥有所需的所有模块。看

此外,允许您和


提供了更方便的方法,例如,以及它们的对应方法。

我会这样做:

my $file = "index.html";
my $document = do {
    local $/ = undef;
    open my $fh, "<", $file
        or die "could not open $file: $!";
    <$fh>;
};
while($. < $skipLines) {<FILE>};
my$file=“index.html”;
我的$document=do{
本地$/=undef;

打开我的$fh,“所有的帖子都有点不习惯用语。习惯用语是:

open my $fh, '<', $filename or die "error opening $filename: $!";
my $data = do { local $/; <$fh> };

打开我的$fh,将
$/
设置为
unde
(请参见jrockway的答案),或者只是连接文件的所有行:

$content = join('', <$fh>);
$content=join(“”,);
建议在任何支持标量的Perl版本上对文件句柄使用标量。

使用:

.

来自:


您可以使用File::Slurp模块一步完成

use File::Slurp;

$all_of_it = read_file($filename); # entire file in scalar
@all_lines = read_file($filename); # one line per element
处理文件中所有行的惯用Perl方法是一次处理一行:

open (INPUT, $file)     || die "can't open $file: $!";
while (<INPUT>) {
    chomp;
    # do something with $_
    }
close(INPUT)            || die "can't close $file: $!";

第三个参数测试输入文件句柄上数据的字节大小,并将这么多字节读入缓冲区$var。

您只能从菱形运算符
获取第一行,因为您在标量上下文中对其进行计算:

$document = <FILE>; 
$document=;
在列表/数组上下文中,菱形操作符将返回文件的所有行

@lines = <FILE>;
print @lines;
@lines=;
打印@行;

这更多的是一个关于如何而不是这样做的建议。我刚刚在一个相当大的Perl应用程序中发现了一个错误。大多数模块都有自己的配置文件。要整体阅读配置文件,我在Internet上的某个地方发现了这行Perl:

# Bad! Don't do that!
my $content = do{local(@ARGV,$/)=$filename;<>};
结果:

After reading a file 3 times redirecting to STDIN: 3
After opening a file using dedicated file handle: 3
read line: 1
read line: 2
(...)
read line: 46
before close: 46
after close: 0
奇怪的是,每一个文件的行计数器
$。
都会增加一个。它不会重置,也不包含行数。并且在打开另一个文件时,在至少读取一行之前,它不会重置为零。在我的情况下,我是这样做的:

my $file = "index.html";
my $document = do {
    local $/ = undef;
    open my $fh, "<", $file
        or die "could not open $file: $!";
    <$fh>;
};
while($. < $skipLines) {<FILE>};
正确关闭文件句柄。

另一种可能的方式:

open my $fh, '<', "filename";
read $fh, my $string, -s $fh;
close $fh;
打开我的$fh,
打开f,“test.txt”
$file=加入“”,

-从我们的文件返回一个行数组(如果
$/
具有默认值
“\n”
),然后
join''
将此数组粘贴到其中。

您可以简单地创建一个子例程:

#Get File Contents
sub gfc
{
    open FC, @_[0];
    join '', <FC>;
}
#获取文件内容
次gfc
{
开放FC,@[0];
加入“”;
}

我会用最简单的方法来做,这样任何人都可以理解发生了什么,即使有更聪明的方法:

my $text = "";
while (my $line = <FILE>) {
    $text .= $line;
}
my$text=”“;
while(我的$line=){
$text.=$line;
}
使用

$document=;
$/
之前是输入记录分隔符,默认为换行符。将其重新定义为
undef
,表示没有字段分隔符。这称为“slurp”模式


其他解决方案,如
undef$/
local$/
(但不是
my$/
)重新声明$/,从而产生相同的效果。

我不知道这是否是一种好的做法,但我以前使用过:

$var = do { local $/; <INPUT> };
($a=<F>);
($a=);

确实应该检查“无法安装”的定义"是的,这是一个常见的问题,并且通常是一个不需要提出的参数。实际上,除了脚本本身,我无法在运行此脚本的整个服务器上修改任何内容。因此,不允许在服务器上的任何位置添加任何文件?将FatPack模块添加到脚本中?而且,看起来您可能正在考虑不要用正则表达式解析HTML。这可能是最好的非cpan方法,因为它既使用3参数打开,又使用输入\记录\分隔符($/)变量本地化到所需的最小上下文。您可能应该解释本地化$/将产生什么效果以及它的用途。如果您不打算解释有关本地化
$/
的任何内容,您可能应该添加链接以获取更多信息。一个很好的分步说明:{local$/;}这里提供了:也许只需说明为什么必须使用
local
而不是
my
@Geremia。关于范围的讨论超出了这个答案的范围。
local$foo=undef
只是Perl最佳实践(PBP)建议的方法。如果我们发布一些代码片段,我认为尽最大努力把它弄清楚是一件好事。向人们展示如何编写非惯用代码是一件好事?如果我在正在编写的代码中看到“local$/=undef”,我的第一个行动将是公开羞辱irc上的作者。(而且我通常对“风格”并不挑剔)好的,我要咬一口:关于“local$/=unde”的mock-worthy到底是什么?如果你的唯一答案是“它不是惯用语”,那么(a)我不太确定(b)那又怎样?我不太确定,因为这是一种非常常见的方法。这又是因为它非常清晰且相当简洁。你可能会对你认为的风格问题更加挑剔。关键是“local$/”是一个众所周知的习惯用法的一部分。如果你在写一些随机代码并编写“local$Foo::Bar=unde;”,这很好。但是在这个非常特殊的情况下,你可能会说和其他人一样的语言,即使它“不太清楚”(我不同意这一点;“本地”的行为是很明确的
After reading a file 3 times redirecting to STDIN: 3
After opening a file using dedicated file handle: 3
read line: 1
read line: 2
(...)
read line: 46
before close: 46
after close: 0
while($. < $skipLines) {<FILE>};
my $content = do{local $/; open(my $f1, '<', $filename) or die $!; my $tmp1 = <$f1>; close $f1 or die $!; $tmp1};
my $content2 = do{local $/; open(my $f2, '<', $filename) or die $!; my $tmp2 = <$f2>; close $f2 or die $!; $tmp2};
my $content3 = do{local $/; open(my $f3, '<', $filename) or die $!; my $tmp3 = <$f3>; close $f3 or die $!; $tmp3};
open my $fh, '<', "filename";
read $fh, my $string, -s $fh;
close $fh;
open f, "test.txt"
$file = join '', <f>
#Get File Contents
sub gfc
{
    open FC, @_[0];
    join '', <FC>;
}
my $text = "";
while (my $line = <FILE>) {
    $text .= $line;
}
 $/ = undef;
($a=<F>);