【发布时间】:2014-05-15 14:55:53
【问题描述】:
好的,所以我在 bash 中编写了一个脚本,通过搜索用户名或 IP 地址来显示 ftp 连接的整个流程。我让它将数据读入一个数组,搜索条件,然后将该进程 id 与其他进程 id 匹配,这样我就可以得到整个流程。
但是性能非常慢,根据专家交流社区其他人的建议,我决定在 perl 中尝试一下。我正在尝试尽可能多地学习,但还有很长的路要走。我正在尝试搜索条件,获取该行的进程 id,然后将所有行读入与该进程 id 匹配的数组,因此我基本上得到了 ftp 连接的整个流程。
我假设我会从文件中读取每一行,对其进行模式匹配,如果它与我正在搜索的 IP 地址匹配,我会将该行复制到一个数组中。然后我在想,在我将这些行读入数组后,我将返回并从每一行中获取进程 ID,对文件进行另一次搜索并将所有与进程 ID 匹配的行放入一个新数组中,然后将数组打印出来。
我有以下代码用于根据文件是否匹配数组中的模式来匹配文件的行。
数组@pids 有以下数据,但还有数百个:
4682
4690
4692
4693
4696
5320
如果我正在阅读的行中有这个数字,那么我将它推送到一个新数组。一旦它到达文件的末尾,它就会回到文件的开头并匹配数组@pids 的下一个元素。然后我将新数组打印到一个文件中。
不幸的是,循环一直持续,有什么办法可以加快速度吗?我假设是因为我一遍又一遍地浏览文件,使事情有点重复,但不知道我应该怎么做。
seek INPUT, 0, 0;
my @flow;
my $count = 0;
my $pid_count = 0;
foreach my $mPID(@pids){
while(my $line = <INPUT>){
if ($line =~ /$mPID/){
push @flow, $line;
}
}
push @flow, "###############\n";
seek INPUT, 0, 0;
}
open (OUTPUT, '>'.$output) or die "Couldn't read $output.\n";
print OUTPUT @flow;
close (OUTPUT);
这是来自以下数据的示例:
Dec 1 23:59:03 ftp1 ftpd[4152]: PASV
Dec 1 23:59:04 ftp1 ftpd[4152]: NLST
Dec 1 23:59:04 ftp1 ftpd[4152]: FTP session closed
Dec 1 23:59:05 ftp1 ftpd[4682]: USER test1
Dec 1 23:59:05 ftp1 ftpd[4682]: PASS password
Dec 1 23:59:08 ftp1 ftpd[4682]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], prd
我从以下位置获取与 IP 匹配的所有 pid 的数据示例:
Dec 1 23:59:08 ftp1 ftpd[4682]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], prd
Dec 1 23:59:10 ftp1 ftpd[4690]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], prod1
Dec 1 23:59:10 ftp1 ftpd[4692]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], prod
Dec 1 23:59:11 ftp1 ftpd[4693]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], test1
Dec 1 23:59:14 ftp1 ftpd[4696]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], test1
Dec 1 23:59:40 ftp1 ftpd[5320]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], test1
Dec 1 23:59:47 ftp1 ftpd[5325]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], prd
Dec 1 23:59:48 ftp1 ftpd[5328]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], prod1
Dec 1 23:59:49 ftp1 ftpd[5329]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], prod
Dec 1 23:59:49 ftp1 ftpd[5330]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], test1
Dec 2 00:00:09 ftp1 ftpd[9876]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], test1
Dec 2 00:00:25 ftp1 ftpd[12830]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], test1
Dec 2 00:00:25 ftp1 ftpd[12832]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], prd
Dec 2 00:00:27 ftp1 ftpd[12850]: FTP LOGIN FROM 192.168.0.2 [192.168.0.2], prod1
谢谢!
【问题讨论】:
-
为什么不循环遍历每一行的所有模式?现在写你阅读文件的每一行
scalar @pids次。 IO 通常是这类问题的瓶颈,如果您可以将其最小化的话。 -
我希望对其进行排序,这就是为什么我在外面有 @pid 循环。
-
这看起来像XY problem。你描述了如何你试图解决你的问题,但没有描述什么你试图解决。我怀疑有更好的方法来解决这个问题,但没有更多细节,很难说。请告诉我们您到底想达到什么目标,我们或许可以推荐一些更好的方法。
-
@user2208986 如果你使用一个 hashref,它的键是 pid,值是如下 mob 显示的行的 arrayref,你仍然可以保持顺序。
-
(您问了一个先前的问题,因为已删除,描述了您要解决的实际问题;根据您对该问题的问题的描述,不需要数组或多次传递通过文件,这就是我发表最后一条评论的原因)