我们有300多个txt文件,其中基本上是电子邮件的复制品,每个txt文件都有以下格式:
To: blabla@hotmail.com
Subject: blabla
From: bla1@hotmail.com
Message: Hello World!
我在脚本上的平台是Windows,一切都是本地的(包括Perl实例)。目的是编写一个脚本,该脚本遍历每个文件(都位于同一目录中),并在from字段中打印出每个“唯一”电子邮件地址的列表。这个概念很简单。
有人能指出我在正确的方向吗?我知道如何开始Perl脚本,我能够读取单个文件并打印所有细节:
#!/usr/local/bin/perl
open (MYFILE, 'emails/email_id_1.txt');
while (<MYFILE>) {
chomp;
print "$_\n";
}
close (MYFILE);
现在,我需要能够读取和打印此文件的第3行,但不仅要执行此活动一次,而且要执行所有文件。我查看了File :: Find模块,这可能有用吗?
答案 0 :(得分:2)
内置glob()
可以为您提供目录中的文件列表:
chdir $dir or die $!;
my @files = glob('*');
您可以使用Tie::File
访问文件的第3行:
use Tie::File;
for (@files) {
tie my @lines, 'Tie::File', $_ or die $!;
print $lines[2], "\n";
}
答案 1 :(得分:2)
什么平台?如果Linux那么简单:
foreach $f (@ARGS) {
# Do stuff
}
然后拨打:
perl mything.pl *.txt
在Windows中,您需要首先展开通配符,因为cmd.exe不会扩展通配符(与Linux shell不同):
@ARGV = map glob, @ARGV
foreach $f (@ARGS) {
# Do stuff
}
然后提取第三行只是读取每一行的简单情况,并在你到达第3行时进行计数,以便你知道打印结果。
答案 2 :(得分:2)
Perl one-liner,windows-version:
perl -wE "@ARGV = glob '*.txt'; while (<>) { say $1 if /^From:\s*(.*)/ }"
它将检查所有行,但只有在找到有效的From:标记时才会打印。
答案 3 :(得分:1)
您使用的是Unix风格的shell吗?您可以在shell中执行此操作,甚至不使用Perl。
grep“^ From:”。/ * |排序| uniq -c“
细分如下:
您的输出看起来像:
3 From: dave@example.com 5 From: foo@bar.example.com etc...
可能的问题: 我不确定你的“From”行会有多复杂,例如:多个地址,不同格式等。
您可以通过几种方式增强该grep步骤,或者将其替换为功能不如您提议的多功能一体脚本的Perl脚本。
如果有任何不清楚的地方,请发表评论。
答案 4 :(得分:1)
这是我的解决方案(我希望这不是作业)。
它检查当前目录中名称以“.txt”结尾的所有文件,不区分大小写(例如,它会找到“foo.TXT”,这可能是您在Windows下所需的)。它还允许行终止符(至少CR-LF和LF)的可能变化,并且不区分大小写地搜索From:
前缀,并允许:
之后的任意空格。
#!/usr/bin/perl
use strict;
use warnings;
opendir my $DIR, '.' or die "opendir .: $!\n";
my @files = grep /\.txt$/i, readdir $DIR;
closedir $DIR;
# print "Got ", scalar @files, " files\n";
my %seen = ();
foreach my $file (@files) {
open my $FILE, '<', $file or die "$file: $!\n";
while (<$FILE>) {
if (/^From:\s*(.*)\r?$/i) {
$seen{$1} = 1;
}
}
close $FILE;
}
foreach my $addr (sort keys %seen) {
print "$addr\n";
}