[英]How to handle files that do not contain a pattern?
我的Perl程序需要幫助。 這個想法是從命令行傳遞模式和文件列表。 如果文件名與模式匹配,則打印文件名。 然后,如果文件名不匹配,則應在文件的文本中查找模式的實例並打印文件名:包含出現的文本的第一行 。
但是,如果用戶在開頭添加-i
選項,則會出現相反的情況。 如果文件名不匹配,請打印。 然后打印任何文本中不包含任何模式實例的文件。
這是我在奮斗的最后一部分,我不確定如何獲取文本中沒有模式的文件。 例如在我的代碼中
#!/usr/bin/perl -w
die("\n Usage: find.pl [-i] <perlRegexPattern> <listOfFiles>\n\n") if(@ARGV<2);
my (@array,$pattern,@filesmatch,@files);
#I can separate files based on name match
($pattern,@array) = ($ARGV[0] eq "-i") ? (@ARGV[1 .. $#ARGV]) : (@ARGV);
foreach(@array){
($_ =~ m/.*\/?$pattern/) ? (push @filesmatch,$_) : (push @files, $_);
}
#and I can get files that contain a pattern match in their text
if($ARGV[0] ne "-i"){
for my $matches(@filesmatch){ #remove path print just file name
$matches =~s/.*\///; #/
print "$matches\n";
}
for my $file(@files){
open(FILE,'<',$file) or die("\nCould not open file $file\n\n");
while(my $line = <FILE>){
if($line =~ m/$pattern/){
$file =~ s/.*\///; #/ remove path print just file name
print "$file: $line";
next;
}
}
}
}
#however I'm not sure how to say this file dosen't have any matches so print it
else{
for my $matches(@files){ #remove path print just file name
$matches =~ s/.*\///;
print "$matches\n";
}
for my $file(@filesmatch){
open(FILE,'<',$file) or die("\nCould not open file $file\n\n");;
while(my $line = <FILE>){...
我不確定是否可以使用grep
之類的方法來執行此操作,但是我在使用Perl的grep
時遇到了困難。
為了根據文件的內容決定是否打印文件,您必須首先讀取文件。 根據您的標准-短語不存在-您必須檢查整個文件。
一種標准方法是使用單獨的變量(“標志”)記錄條件,然后返回打印
my $has_match;
while (<$fh>) {
if (/$pattern/) {
$has_match = 1;
last;
}
}
if (not $has_match) {
seek $fh, 0, 0; # rewind to the beginning
print while <$fh>;
}
可以通過首先將文件讀入變量並使用標簽來簡化此操作(另請參見perlsyn )
FILE: foreach my $file (@filesmatch) {
open my $fh, '<', $file or die "Can't open $file: $!";
my @lines = <$fh>;
for (@lines) {
next FILE if /$pattern/;
}
print for @lines;
}
請注意,在循環的中間跳過迭代並不是最干凈的方法,因為必須牢記循環的其余部分可能不會運行。
每個文件都會被首先讀取,因此我們不會讀取兩次,但是如果其中任何一個文件可能很大,都不要這樣做。
如果有任何命令行處理,最好使用模塊。 Getopt :: Long很不錯。
use Getopt::Long;
my ($inverse, $pattern);
GetOptions('inverse|i' => \$inverse, 'pattern=s' => \$pattern)
or usage(), exit;
usage(), exit if not $pattern or not @ARGV;
sub usage { say STDERR "Usage: $0 ... " }
以progname [-i] --patern PATTERN files
調用程序。 該模塊提供了很多功能,請參閱文檔。 例如,在這種情況下,您也可以只使用-p PATTERN
。
當GetOptions
解析命令行時,已提交的選項已從@ARGV
中刪除,其中剩下的是文件名。 並且您可以使用$inverse
變量很好地進行決策。
請有use warnings;
( 不是 -w
)並use strict;
在每個程序的頂部。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.