Python 如果一个非常大的文件不包含换行符,如何从中复制匹配项?
问题是,我无法避免使用包含新行的超大文件:Python 如果一个非常大的文件不包含换行符,如何从中复制匹配项?,python,linux,bash,perl,grep,Python,Linux,Bash,Perl,Grep,问题是,我无法避免使用包含新行的超大文件: <a>text1</a>...gigabytes of data here, all in one single line...[a text to extract b> 它只会给出一个错误:内存耗尽(这是一个相关问题:)。 sed和awk都不允许使用这样的文件。那么,我应该如何从中提取匹配项呢 #!/usr/bin/perl use strict; use warnings; use constant BLOCK_
<a>text1</a>...gigabytes of data here, all in one single line...[a text to extract b>
它只会给出一个错误:内存耗尽(这是一个相关问题:)。sed和awk都不允许使用这样的文件。那么,我应该如何从中提取匹配项呢
#!/usr/bin/perl
use strict;
use warnings;
use constant BLOCK_SIZE => 64*1024;
my $buf = "";
my $searching = 1;
while (1) {
my $rv = read(\*STDIN, $buf, BLOCK_SIZE, length($buf));
die($!) if !defined($rv);
last if !$rv
while (1) {
if ($searching) {
my $len = $buf =~ m{\[(?:a|\z)} ? $-[0] : length($buf);
substr($buf, 0, $len, '');
last if $buf !~ s{^\[a}{};
$searching = 0;
} else {
my $len = $buf =~ m{b(?:>|\z)} ? $-[0] : length($buf);
print substr($buf, 0, $len, '');
last if $buf !~ s{^b>}{};
print("\n");
$searching = 1;
}
}
}
做出了很多假设:
- 假定起始标记的拼写正确
[a
- 假定结束标记的拼写正确
b>
- 假设每个开始标记都有相应的结束标记
- 假设每个结束标记都有相应的开始标记
- 假设在
和[a
之间找不到b>
[a
- 使用
。这将确保只有换行符是行终止符--text
- 使用
。这将确保只有null字节是行终止符--null data
您是否尝试过
tr'\0'\n'
我测试了tr'\0'\n'path/to/output.txt
现在,它对输入没有任何影响。output.txt仍然保持不变。基于行的工具不起作用。您最好用Perl或Python编写一个脚本来处理该文件。我编辑了相应地,e标记:)但奇怪的是,我认为这是一种非常常见的操作(例如),但在网上搜索没有显示这种脚本的示例…1.如何在控制台中使用它(即,如何指定输入和输出文件的名称)?2.如果我想复制\[a.*?b>
匹配项怎么办?我不是在问标记(我发布了*?
作为一个非常基本的示例),我想复制基于正则表达式的匹配。我相应地编辑了示例。3.如果匹配大小超过32KB,会发生什么?我准备跳过这些匹配,但脚本会发生什么?1.a.pl重复限制在这里不适用。大多数情况下(仅?)对于{m,n}
。对不起,我不是一个Perl程序员。1.
是什么?3.我想,如果文件开头某处包含[a
,结尾包含b>
,会有一个大问题?内存不足!避免这种问题的唯一方法是在regex中指定一个限制,如[a.{064000}b>
,对吗?1.重定向输入。您已经知道如何重定向输出。2.不,您可以假设b>
即将出现,并在找到[a
后立即开始打印。
#!/usr/bin/perl
use strict;
use warnings;
use constant BLOCK_SIZE => 64*1024;
my $buf = "";
my $searching = 1;
while (1) {
my $rv = read(\*STDIN, $buf, BLOCK_SIZE, length($buf));
die($!) if !defined($rv);
last if !$rv
while (1) {
if ($searching) {
my $len = $buf =~ m{\[(?:a|\z)} ? $-[0] : length($buf);
substr($buf, 0, $len, '');
last if $buf !~ s{^\[a}{};
$searching = 0;
} else {
my $len = $buf =~ m{b(?:>|\z)} ? $-[0] : length($buf);
print substr($buf, 0, $len, '');
last if $buf !~ s{^b>}{};
print("\n");
$searching = 1;
}
}
}