sed/perl正则表达式非常慢

sed/perl正则表达式非常慢,perl,bash,sed,Perl,Bash,Sed,这篇文章中的私人信息。已删除。在分析我工作中的日志时,我会执行以下操作:将文件拆分为N个部分(N=num\u处理器);将拆分点对齐到\n。启动N个线程来处理每个部件。工作速度非常快,但硬盘是瓶颈。在解析我工作中的日志时,我会这样做:将文件拆分为N个部分(N=num\u个处理器);将拆分点对齐到\n。启动N个线程来处理每个部件。工作速度非常快,但硬盘驱动器是瓶颈。bash脚本的问题在于,虽然非常灵活和强大,但它几乎可以为任何事情创建新的进程,而且分叉成本很高。在循环的每个迭代中,都会产生3个×ec

这篇文章中的私人信息。已删除。

在分析我工作中的日志时,我会执行以下操作:将文件拆分为N个部分(N=num\u处理器);将拆分点对齐到\n。启动N个线程来处理每个部件。工作速度非常快,但硬盘是瓶颈。

在解析我工作中的日志时,我会这样做:将文件拆分为N个部分(N=num\u个处理器);将拆分点对齐到\n。启动N个线程来处理每个部件。工作速度非常快,但硬盘驱动器是瓶颈。

bash脚本的问题在于,虽然非常灵活和强大,但它几乎可以为任何事情创建新的进程,而且分叉成本很高。在循环的每个迭代中,都会产生3个×
echo
、2个×
awk
、1个×
sed
和1个×
perl
。将自己限制为一个进程(因此,一种编程语言)将提高性能

然后,每次调用
perl
时,您都要重新读取
output.txt
。IO总是很慢,所以如果你有内存的话,缓冲文件会更有效

如果没有散列冲突,多线程就可以工作,但很难编程。与将Perl转换为多线程Perl相比,简单地转换为Perl将获得更大的性能提升。[引文]

你可能会这样写

#!/usr/bin/perl
use strict; use warnings;
open my $cracked, "<", "cracked.txt" or die "Can't open cracked";
my @data = do {
  open my $output, "<", "output.txt" or die "Can't open output";
  <$output>;
};

while(<$cracked>) {
  my ($hash, $seed, $pwd) = split /:/, $_, 3;
  # transform $hash here like "$hash =~ s/foo/bar/g" if really neccessary

  # say which line we are at
  print "at line $. with pwd=$pwd\n";

  # do substitutions in @data
  s/\Q$hash\E/$hash ( $pwd )/ for @data;
  # the \Q...\E makes any characters in between non-special,
  # so they are matched literally.
  # (`C++` would match many `C`s, but `\QC++\E` matches the character sequence)
}

# write @data to the output file
实际上,您将存储对一个数组的引用,该数组包含哈希树中包含哈希代码的所有行,因此前面的行更倾向于

my %data;
for my $line (@data) {
   my $key = parse_line($line);
   push @$data{$key}, $line;
}
...; 
s/\Q$hash\E/$hash ( $pwd )/ for @{$data{$hash}}; # is still faster!

另一方面,包含8E7元素的散列可能无法很好地执行。答案在于基准测试。

bash脚本的问题在于,尽管非常灵活和强大,但它几乎可以为任何东西创建新的过程,而且分叉成本高昂。在循环的每个迭代中,都会产生3个×
echo
、2个×
awk
、1个×
sed
和1个×
perl
。将自己限制为一个进程(因此,一种编程语言)将提高性能

然后,每次调用
perl
时,您都要重新读取
output.txt
。IO总是很慢,所以如果你有内存的话,缓冲文件会更有效

如果没有散列冲突,多线程就可以工作,但很难编程。与将Perl转换为多线程Perl相比,简单地转换为Perl将获得更大的性能提升。[引文]

你可能会这样写

#!/usr/bin/perl
use strict; use warnings;
open my $cracked, "<", "cracked.txt" or die "Can't open cracked";
my @data = do {
  open my $output, "<", "output.txt" or die "Can't open output";
  <$output>;
};

while(<$cracked>) {
  my ($hash, $seed, $pwd) = split /:/, $_, 3;
  # transform $hash here like "$hash =~ s/foo/bar/g" if really neccessary

  # say which line we are at
  print "at line $. with pwd=$pwd\n";

  # do substitutions in @data
  s/\Q$hash\E/$hash ( $pwd )/ for @data;
  # the \Q...\E makes any characters in between non-special,
  # so they are matched literally.
  # (`C++` would match many `C`s, but `\QC++\E` matches the character sequence)
}

# write @data to the output file
实际上,您将存储对一个数组的引用,该数组包含哈希树中包含哈希代码的所有行,因此前面的行更倾向于

my %data;
for my $line (@data) {
   my $key = parse_line($line);
   push @$data{$key}, $line;
}
...; 
s/\Q$hash\E/$hash ( $pwd )/ for @{$data{$hash}}; # is still faster!

另一方面,包含8E7元素的散列可能无法很好地执行。答案在于基准测试。

我们应该帮助您破解密码,因为…?也许您需要某种输出功能?您有分隔符等等1。谷歌“彩虹表”。2.使用数据库。3.长大点,不要试图破解密码。我们应该帮助你破解密码,因为…?也许你需要某种输出功能?您有分隔符等等1。谷歌“彩虹表”。2.使用数据库。3.长大点,别再试图破解密码了。@JoshuaRogers很遗憾,我不知道任何awk,但你可以像解析
my($hash,$seed,$pwd)=/^([^:]+):(.{3}):(.+)/
那样解析每一行输入。这会将种子字段视为一个固定宽度的列。@JoshuaRogers我不知道如果正则表达式替换使用了右括号,并且您没有使用
printf
或任何奇怪的东西,为什么会以这种方式切断输出。(对
$NF
:awk相当于
my($hash,$pwd)=@{[split/:/,$\u]}[0,-1]
)@JoshuaRogers很遗憾,我不知道任何awk,但是你可以像
my($hash,$seed,$pwd)=/^([^:]+):(.{3}:(.+)/
那样解析每一个输入行。这会将种子字段视为一个固定宽度的列。@JoshuaRogers我不知道如果正则表达式替换使用了右括号,并且您没有使用
printf
或任何奇怪的东西,为什么会以这种方式切断输出。(对
$NF
:awk将相当于
my($hash,$pwd)=@{[split/:/,$]}[0,-1]