我有兩個檔案。File1 包含電子郵件地址串列。File2 包含域串列。
我想在使用 Perl 腳本匹配確切的域后過濾掉所有的電子郵件地址。
我正在使用下面的代碼,但我沒有得到正確的結果。
#!/usr/bin/perl
#use strict;
#use warnings;
use feature 'say';
my $file1 = "/home/user/domain_file" or die " FIle not found\n";
my $file2 = "/home/user/email_address_file" or die " FIle not found\n";
my $match = open(MATCH, ">matching_domain") || die;
open(my $data1, '<', $file1) or die "Could not open '$file1' $!\n";
my @wrd = <$data1>;
chomp @wrd;
# loop on the fiile to be searched
open(my $data2, '<', $file2) or die "Could not open '$file2' $!\n";
while(my $line = <$data2>) {
chomp $line;
foreach (@wrd) {
if($line =~ /\@$_$/) {
print MATCH "$line\n";
}
}
}
檔案 1
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
檔案2
yahoo.com
gmail.com
預期產出
[email protected]
[email protected]
uj5u.com熱心網友回復:
首先,由于您似乎在 *nix 上,您可能想檢查一下grep -f,它可以從給定檔案中獲取搜索模式。我不是專家grep,但我會嘗試檔案并“匹配整個單詞”,這應該相當容易。
第二:您的 Perl 代碼可以改進,但可以按預期作業。如果您按照代碼所示將電子郵件和域放入檔案中。可能是你把檔案弄混了。
如果我運行您的代碼,僅修復路徑并將域保存在 file1 中,它會創建檔案matching_domain并包含您預期的輸出:
[email protected]
[email protected]
所以我不知道你認為你的問題是什么(因為你沒有說)。也許您期望它將輸出列印到終端。無論哪種方式,它確實有效,但有一些事情需要解決。
#use strict;
#use warnings;
洗掉這兩個是一個巨大的錯誤。在撰寫 Perl 時你會犯的最大錯誤。它不會洗掉您的錯誤,只是隱藏它們。您將花費 10 倍的時間修復錯誤。取消注釋這是您解決此問題的第一件事。
use feature 'say';
你從來不用這個。例如,您可以print MATCH "$line\n"用say MATCH $line更簡潔的方式替換。
my $file1 = "/home/user/domain_file" or die " FIle not found\n";
my $file2 = "/home/user/email_address_file" or die " FIle not found\n";
這是非常不正確的。您正在對變數的創建設定條件。如果條件不成立,變數是否存在?不要這樣做。我假設這是為了檢查檔案是否存在,但這不是這樣做的。要檢查檔案是否存在,您可以使用-e, 記錄為perldoc "-X"(各種檔案測驗)。
"/home/user..."此外,就 Perl 條件而言,字串形式的陳述句是 TRUE(“真”)。僅當它是"0"(零)、""(空)或undef(未定義)時才為假。所以你的or條款永遠不會被執行。eg"foo" or die永遠不會死。
最后,這個測驗毫無意義,因為open無論如何你都會在你的宣告中測驗它。如果檔案不存在,打開將失敗,您的程式將die.
my $match = open(MATCH, ">matching_domain") || die;
這也是非常不正確的。首先,你永遠不會使用$match變數。其次,我敢打賭它不包含您認為的內容。(它包含一個說明是否open成功的布林值,請參閱perldoc -f open)第三,再次,不要my對變數的宣告設定條件,這是一個壞主意。
該陳述句的真正含義是$match將包含 的回傳值open或 的回傳值die。這應該很簡單:
open my $match, ">", "matching_domain" or die "Cannot open '$match': $!;
此外,將三個引數open與顯式打開模式一起使用,并使用詞法檔案句柄,就像您在其他地方所做的那樣。
除了我已經糾纏你的所有東西之外,還有一件事:我不建議對像這樣的小程式進行硬編碼輸出檔案。如果要重定向輸出,請使用 shell 重定向:perl foo.pl > output.txt。我認為這就是促使您認為您的代碼有問題的原因:您看不到輸出。
除此之外,您的代碼很好,據我所知。您可能想要chomp來自域檔案的行,但這并不重要。還要記住縮進是一件好事,它可以幫助您閱讀代碼。我在評論中提到了這一點,但由于某種原因它被洗掉了。不過這很重要。
祝你好運!
uj5u.com熱心網友回復:
這假定標記的行在File1指向的檔案中,$file1并且標記的行在File2指向的檔案中$file2。
你有你的變數交換。你想匹配什么是$line反對$_,而不是相反:
# loop on the file to be searched
open( my $data2, '<', $file2 ) or die "Could not open '$file2' $!\n";
while ( my $line = <$data2> ) {
chomp $line;
foreach (@wrd) {
if (/\@$line$/) {
print MATCH "$_\n";
}
}
}
您應該取消注釋warnings和strict行:
use strict;
use warnings;
warnings向您顯示or die檢查并未真正按照您在檔案名分配陳述句中的預期方式作業。只需使用:
my $file1 = "/home/user/domain_file";
my $file2 = "/home/user/email_address_file";
您已經在檢查它們所屬的位置(在 上open)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/493832.html
標籤:perl
