Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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
Arrays Perl-在服务器上打开大型txt文件,并创建/保存为每个100行的较小文件_Arrays_Perl_File - Fatal编程技术网

Arrays Perl-在服务器上打开大型txt文件,并创建/保存为每个100行的较小文件

Arrays Perl-在服务器上打开大型txt文件,并创建/保存为每个100行的较小文件,arrays,perl,file,Arrays,Perl,File,我正在尝试这样做: 我用FTP传输一个大文件,单个字约144000个,每行一个字 我需要打开上传的文件,并创建最多100行的文件 每行01.txt、02.txt等的单词 我想处理100从原始文件中删除 创建100的文件后 服务器是共享的,但如果需要,我可以安装模块 现在,我下面的代码非常粗糙,因为我的知识非常有限。一个问题是将整个文件打开到一个数组中?共享服务器没有足够的内存,我想无法打开如此大的文件并一次性读取内存?我只想要前100行。下面是打开一个小到可以加载的文件,并在一个数组中放入100

我正在尝试这样做:

我用FTP传输一个大文件,单个字约144000个,每行一个字

我需要打开上传的文件,并创建最多100行的文件 每行01.txt、02.txt等的单词

我想处理100从原始文件中删除 创建100的文件后

服务器是共享的,但如果需要,我可以安装模块

现在,我下面的代码非常粗糙,因为我的知识非常有限。一个问题是将整个文件打开到一个数组中?共享服务器没有足够的内存,我想无法打开如此大的文件并一次性读取内存?我只想要前100行。下面是打开一个小到可以加载的文件,并在一个数组中放入100行。没有别的了。我打字很快,所以prob有几个问题,但是,显示我有限的知识和需要帮助

 use vars qw($Word @Words $IN);
 my $PathToFile = '/home/username/public/wordlists/Big-File-Of-Words.txt';
 my $cnt= '0';
 open $IN, '<', "$PathToFile" or die $!;
 while (<$IN>) {
    chomp;
    $Word = $_; 
    $Word=~ s/\s//g;
    $Word = lc($Word);
    ######
    if ($cnt <= 99){
        push(@Words,$Word);
    }
    $cnt++;
}
close $IN;
但我得到:

syntax error at split-up-big-file.pl line 12, near "sed 's/ *//g'"
Can't find string terminator "'" anywhere before EOF at split-up-big-file.pl line 12.
最后: 我想出了一个有效的快速解决方案。不漂亮:

    #!/usr/bin/perl -w
BEGIN {
my $b__dir = (-d '/home/username/perl'?'/home/username/perl':( getpwuid($>) )[7].'/perl');
unshift @INC,$b__dir.'5/lib/perl5',$b__dir.'5/lib/perl5/x86_64-linux',map { $b__dir . $_ } @INC;
}
use strict;
use warnings;
use CGI;
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
use diagnostics;
print CGI::header();
my $sourcefile = '/home/username/public_html/test/bigfile.txt';
my $rowlimit   = 100;
my $cnt= '1';
open(IN, $sourcefile) or die "Failed to open $sourcefile";
my $outrecno = 1;
while(<IN>) {
  if($outrecno == 1) {
  my $filename= $cnt.'.txt';
    open OUT, ">$filename" or die "Failed to create $filename";
      $cnt++;
  }
  print OUT $_;
  if($outrecno++ == $rowlimit) {
    $outrecno = 1;
    close FH;
  }
}
close FH;

我在这里找到了足够的信息让我走。谢谢…

有一个非Perl解决方案,您可能会发现它很有趣

$ split -l 100 -a6 /home/username/public/wordlists/Big-File-Of-Words.txt words.
这将把你的大文件中的单词分割成一堆文件,每个文件不超过100行。文件名将以单词开头,后缀范围从AAAAA到ZZZZZ。因此,您将拥有words.aaaaaa、words.aaaaab、words.aaaaac等。然后,您可以将所有这些文件重新组合到word列表中,如下所示:

$ cat words.* > reconstituted_word_list.txt
当然,您希望消除空格,同时将单词全部小写:

$ WORD_LIST=/home/username/public/wordlists/Big-File-Of-Words.txt
$ sed 's/ *//g' $WORD_LIST | tr '[A-Z]' '[a-z]' | split -l 100 -a6 - words.
tr是转换命令,它将把所有大写字母改为小写字母。拆分会拆分文件,sed会删除空格

Unix的一大优势是它的文件处理能力。将大文件拆分成小文件并重新构建它们是一项常见的任务。也许你有一个很大的文件,但是一堆软盘不能容纳超过100K的软盘。也许您试图使用UUCP将这些文件复制到另一台计算机上,文件传输大小有10K限制。也许你正在通过电子邮件进行FTP,而系统无法处理大于5K的文件


无论如何,我之所以提出它,是因为在您的情况下,它可能比编写Perl脚本更容易解决问题。我是Perl的大作家,Perl可以比shell脚本更好更快地处理任务。然而,在本例中,这是一个在shell中处理的简单任务。

有一个非Perl解决方案,您可能会发现它很有趣

$ split -l 100 -a6 /home/username/public/wordlists/Big-File-Of-Words.txt words.
这将把你的大文件中的单词分割成一堆文件,每个文件不超过100行。文件名将以单词开头,后缀范围从AAAAA到ZZZZZ。因此,您将拥有words.aaaaaa、words.aaaaab、words.aaaaac等。然后,您可以将所有这些文件重新组合到word列表中,如下所示:

$ cat words.* > reconstituted_word_list.txt
当然,您希望消除空格,同时将单词全部小写:

$ WORD_LIST=/home/username/public/wordlists/Big-File-Of-Words.txt
$ sed 's/ *//g' $WORD_LIST | tr '[A-Z]' '[a-z]' | split -l 100 -a6 - words.
tr是转换命令,它将把所有大写字母改为小写字母。拆分会拆分文件,sed会删除空格

Unix的一大优势是它的文件处理能力。将大文件拆分成小文件并重新构建它们是一项常见的任务。也许你有一个很大的文件,但是一堆软盘不能容纳超过100K的软盘。也许您试图使用UUCP将这些文件复制到另一台计算机上,文件传输大小有10K限制。也许你正在通过电子邮件进行FTP,而系统无法处理大于5K的文件


无论如何,我之所以提出它,是因为在您的情况下,它可能比编写Perl脚本更容易解决问题。我是Perl的大作家,Perl可以比shell脚本更好更快地处理任务。然而,在本例中,这是一个在shell中很容易处理的任务。

这里是一个纯Perl解决方案。问题是您希望在每100行之后创建文件

为了解决这个问题,我有两个循环。一个是无限循环,另一个循环100次。在进入内部循环之前,我创建了一个用于写入的文件,并每行写入一个单词。当内部循环结束时,我关闭文件,增加$output\u file\u num,然后打开另一个文件进行输出

一些变化:

我使用警告;并使用strict,当您指定需要Perl版本5.12.0或更高版本时,会包括strict。 不要使用vars;。这是过时的。如果必须使用包变量,请使用我们的而不是我的声明变量。什么时候应该使用包变量?如果你不得不问这个问题,你可能不需要包变量。99.999%的情况下,只需使用my来声明变量。 我使用常量来定义word文件。这样可以在需要时轻松移动文件。 我的s/./../不仅删除了开头和结尾的空格,还为我将单词小写。^\s*?\s*$删除整行,但捕获单词sans spa ces在单词的开头和结尾。那个女孩?就像。*,但不贪婪。它将尽可能匹配最小值,在本例中,该值不包括单词末尾的空格。 注:我定义了一个标签输入单词列表。我用这个来迫使我的内楦退出外环。 我利用了$output\u word\u list\u fh仅在循环中定义这一事实。一旦我离开循环,文件将自动为我关闭,因为$output\u word\u list\u fh超出范围。 该计划:

#!/usr/bin/env perl

use 5.12.0;
use warnings;
use autodie;

use constant WORD_FILE => "/home/username/public/wordlists/Big-File-Of-Words.txt";

open my $input_word_list_fh, "<", WORD_FILE;

my $output_file_num = 0;

INPUT_WORD_LIST:
for (;;) {
    open my $output_word_list_fh, ">", sprintf "%05d.txt", $output_file_num;
    for my $line (1..100) {
        my $word;
        if ( not $word = <$input_word_list_fh> ) {
            last INPUT_WORD_LIST;
        }
        chomp $word;
        $word =~ s/^\s*(.*?)\s*$/\L$1\E/;
        say {$output_word_list_fh} "$word";
    }
    close $output_word_list_fh;
    $output_file_num += 1;
}
close $input_word_list_fh;

这里是一个纯Perl解决方案。问题是您希望在每100行之后创建文件

为了解决这个问题,我有两个循环。一个是无限循环,另一个循环100次。在进入内部循环之前,我创建了一个用于写入的文件,并每行写入一个单词。当内部循环结束时,我关闭文件,增加$output\u file\u num,然后打开另一个文件进行输出

一些变化:

我使用警告;并使用strict,当您指定需要Perl版本5.12.0或更高版本时,会包括strict。 不要使用vars;。这是过时的。如果必须使用包变量,请使用我们的而不是我的声明变量。什么时候应该使用包变量?如果你不得不问这个问题,你可能不需要包变量。99.999%的情况下,只需使用my来声明变量。 我使用常量来定义word文件。这样可以在需要时轻松移动文件。 我的s/./../不仅删除了开头和结尾的空格,还为我将单词小写。^\s*.?\s*$删除整行,但在单词的开头和结尾捕获单词sans空格。那个女孩?就像。*,但不贪婪。它将尽可能匹配最小值,在本例中,该值不包括单词末尾的空格。 注:我定义了一个标签输入单词列表。我用这个来迫使我的内楦退出外环。 我利用了$output\u word\u list\u fh仅在循环中定义这一事实。一旦我离开循环,文件将自动为我关闭,因为$output\u word\u list\u fh超出范围。 该计划:

#!/usr/bin/env perl

use 5.12.0;
use warnings;
use autodie;

use constant WORD_FILE => "/home/username/public/wordlists/Big-File-Of-Words.txt";

open my $input_word_list_fh, "<", WORD_FILE;

my $output_file_num = 0;

INPUT_WORD_LIST:
for (;;) {
    open my $output_word_list_fh, ">", sprintf "%05d.txt", $output_file_num;
    for my $line (1..100) {
        my $word;
        if ( not $word = <$input_word_list_fh> ) {
            last INPUT_WORD_LIST;
        }
        chomp $word;
        $word =~ s/^\s*(.*?)\s*$/\L$1\E/;
        say {$output_word_list_fh} "$word";
    }
    close $output_word_list_fh;
    $output_file_num += 1;
}
close $input_word_list_fh;

这里是一个基于对代码稍加修改的解决方案,它应该按照您希望的方式工作

它在输入文件的所有行中循环,并在每100行中写入自上次写入或开始以来遇到的单词列表。eof$IN支票用于捕获剩余的行(如果它们小于100)

use strict;
use warnings;

my $PathToFile = '/home/username/public/wordlists/Big-File-Of-Words.txt';

open my $IN, '<', "$PathToFile" or die $!;

my $cnt = 0;
my $cnt_file = 0;
my @Words;

while ( my $Word = <$IN> ) {
    chomp $Word; 
    $Word =~ s/\s//g;
    $Word = lc($Word);
    ######

    push(@Words,$Word);
    if ( !(++$cnt % 100) || eof($IN) ) {
       $cnt_file++;
       open my $out_100, '>', "file_$cnt_file.txt" or die $!;
       print  $out_100 join("\n", @Words), "\n";
       close $out_100;
       @Words = ();
    }
}

这里是一个基于对代码稍加修改的解决方案,它应该按照您希望的方式工作

它在输入文件的所有行中循环,并在每100行中写入自上次写入或开始以来遇到的单词列表。eof$IN支票用于捕获剩余的行(如果它们小于100)

use strict;
use warnings;

my $PathToFile = '/home/username/public/wordlists/Big-File-Of-Words.txt';

open my $IN, '<', "$PathToFile" or die $!;

my $cnt = 0;
my $cnt_file = 0;
my @Words;

while ( my $Word = <$IN> ) {
    chomp $Word; 
    $Word =~ s/\s//g;
    $Word = lc($Word);
    ######

    push(@Words,$Word);
    if ( !(++$cnt % 100) || eof($IN) ) {
       $cnt_file++;
       open my $out_100, '>', "file_$cnt_file.txt" or die $!;
       print  $out_100 join("\n", @Words), "\n";
       close $out_100;
       @Words = ();
    }
}

如果您有shell访问权限,可以使用命令行工具split执行此操作,如下所示:split-l 100/home/username/public/wordlist/Big-File-Of-Words.txt请参见此处的手册页:如果您有shell访问权限,您可以使用命令行工具split这样做:split-l 100/home/username/public/wordlist/Big-File-Of-Words.txt请参见此处的手册页:W-谢谢。现在进行试驾。很快回来。谢谢你,但我不知道如何使用此代码。这可能是一个很好的例子,但我确实需要一个解决方案,我可以在一个简单的Perl脚本中实现,我可以扩展它。很抱歉。@Student33这是Unix的。最后一个例子应该做你提到的所有事情。是的,我理解。我想。见我的附加问题和问题,我试图实现上述。W-谢谢。现在进行试驾。很快回来。谢谢你,但我不知道如何使用此代码。这可能是一个很好的例子,但我确实需要一个解决方案,我可以在一个简单的Perl脚本中实现,我可以扩展它。很抱歉。@Student33这是Unix的。最后一个例子应该做你提到的所有事情。是的,我理解。我想。请参阅我在尝试实现上述功能时遇到的附加问题和问题。这一问题只会给我一个500服务器错误。我添加了使用警告;使用CGI::Carp QWFatastoBrowser警告浏览器;但是,没有打印只是500个内部服务器错误。我没有将此设置为CGI进程。你在原始档案中没有提到。试图写入磁盘可能会导致错误。这一次只给了我一个500服务器错误。我添加了使用警告;使用CGI::Carp QWFatastoBrowser警告浏览器;但是,没有打印只是500个内部服务器错误。我没有将此设置为CGI进程。你在原始档案中没有提到。尝试写入磁盘可能会导致错误。