保存数组中的所有数据,过滤掉重复的数据,比较数组之间的数据并删除匹配的数据



我的脚本有一些问题。 问题是:

  1. 当我打印出来时,$str或@matchedPath的值有时是空白的。它不是随机的,它只发生在表.txt文件中的某些路径上,我无法弄清楚,为什么?
  2. 如何打印像结果一样,因为我找不到正确的文件位置或表的目录.txt文件,因为我将所有路径位置放在一个数组中,对其进行过滤并与表.txt匹配的正确文件位置进行比较,因此,打印出来时缺少某些位置。

/home/is/latest/table.txt 文件包含的示例路径,粗体文本是 table.txt 中想要的路径,

##WHAT PATH IS_THAT,Backup
a   b/c/d   B
a   b/c/d/e  B
a   b/c/d/e/f  B
a   b/c/d/g  B

/home/are/latest/table.txt 文件包含的示例路径,中间的文本是 table.txt 中想要的路径,

##WHAT PATH IS_THAT,Backup
a   b/c/d/j B

例如列表.txt文件包含,

rty/b
uio/b/c
qwe/b/c/d
asd/b/c/d/e
zxc/b/c/d/e/f
vbn/c/d/e
fgh/j/k/l

预期成果:

Unmatched Path         : b/c/d/g
table.txt file location: /home/is/latest/table.txt
Unmatched Path         : b/c/d/j
table.txt file location: /home/are/latest/table.txt

以下是我的详细脚本,

#!/usr/perl/5.14.1/bin/perl 
# I want to make a script that automatically compare the path in table.txt with list.txt
#table.txt files is located under a parent directory and it differs in the subdirectory.
#There is about 10 table.txt files and each one of it need to compare with list.txt
#The objective is to print out the path that are not in the list.txt
use strict;
use warnings;
use Switch;
use Getopt::Std;
use Getopt::Long;
use Term::ANSIColor qw(:constants);
use File::Find::Rule;
use File::Find;
use File::Copy;
use Cwd;
use Term::ANSIColor;
my $path1='/home';                                                      #Automatically search all table.txt file in this directory even in subdirectory
my $version='latest';                                                   #search the file specified subdirectory e.g. /home/is/latest/table.txt and /home/are/latest/table.txt
my $path2='/list.text';                                                 #there is about 10 table.txt files which contain specified paths in it.
$path1 =~ s/^s+|s+$//g;
$version =~ s/^s+|s+$//g;
$path2 =~ s/^s+|s+$//g;
my @files = File::Find::Rule->file()
->name( 'table.txt' )
->in( "$path1" );
my @symlink_dirs = File::Find::Rule->directory->symlink->in($path1);      #If the directory is a symlink, in my case 'latest' is a symlink directory
print colored (sprintf ("nntSUMMARY REPORT"),'bold','magenta');
print  "nn_______________________________________________________________________________________________________________________________________________________nn";
if ($version eq "latest")
{
foreach my $dir (@symlink_dirs) 
{
my @filess = File::Find::Rule->file()
->name( 'table.txt' )
->in( "$path1" );
my $symDir=($dir."/"."table.txt");
$symDir =~ s/^s+|s+$//g;
my $wantedPath=$symDir;
my $path_1 = $wantedPath;
function($path_1);      
}
}
else 
{
for my $file (@files)   
{
if ($file =~ m/.*$version.*/)
{
my $wantedPath=$file;
my $path_1 = $wantedPath;
function($path_1);  
}
}
}
sub function
{
my $path_1 = $_[0];
open DATA, '<', $path_1 or die "Could not open $path_1: $!";
my $path_2 = "$path2";
open DATA1, '<', $path_2 or die "Could not open $path_2: $!";
################# FOCUSED PROBLEM AREA ##############################       
my @matchedPath;
my @matched_File_Path;
my @unmatchedPath;
my @unmatched_File_Path;
my @s2 = <DATA1>;
while(<DATA>)
{
my $s1 = $_;
if ($s1 =~ /^#.*/) 
{
next;
}
if ($s1 =~ /(.*)s+(.*)s+(.*)s+/) 
{
my $str=($2);
$str =~ s/s+//g;
for my $s2 (@s2)
{
if ($s2 =~ /.*$str/)
{
push @matchedPath,$str;                                      
push @matched_File_Path,$path_1;                                
print "matched Path: $strnt$path_1n"; #I don't understand, sometimes I get empty $str value in this. Can anyone help me?
last;
}
else
{
#print "unmatch:$strnt$path_1n";                     
push @unmatchedPath,$str;                                   
@unmatched_File_Path,$path_1;
}
}
}
}
foreach (@unmatchedPath)
{print "unmatch path: $_n";}        
foreach (@matchedPath)
{print "nmatch path: $_nn";}     
foreach (@unmatched_File_Path)       
{print "unmatch File Path: $_n";}
foreach (@matched_File_Path)         
{print "match File Path: $_n";}
my @filteredUnmatchedPath = uniq(@unmatchedPath);                   
my @filteredUnmatched_IP_File_Path =uniq(@unmatched_IP_File_Path); 
@filteredUnmatchedPath = grep {my $filteredPath = $_; not grep $_ eq $filteredPath, @matchedPath} @filteredUnmatchedPath;
}
print "@filteredUnmatchedPathn";   
print "@filteredUnmatched_IP_File_Pathn";
sub uniq 
{
my %seen;
grep !$seen{$_}++, @_;
}

close(DATA);
close(DATA1);
print  "_________________________________________________________________________________________________________________________________________________________nn";

我认为使用哈希要简单得多
,这是我尝试过的: 您必须将@all_path替换为包含存在表的每个路径的数组

use strict;
use warnings;
my @all_path =("some/location/table.txt","some/location_2/table.txt");
my %table_paths;
my %list_paths;
foreach my $path (@all_path)
{
open (my $table, "<", $path) or die ("error opening file");
#we create hash, each key is a path
while (<$table>)
{
chomp;
#only process lines starting with "a" as it seems to be the format of this file
$table_paths{(split)[1]}=$path if (/^a/); #taking the 2nd element in each line
}
close $table;
}
open (my $list, "<", "list.txt") or die ("error opening file");
#we create hash, each key is a path
while (<$list>)
{
chomp;
$list_paths{$_}=1;
}
close $list;
#now we delete from table_paths common keys with list, that lefts unmathed
foreach my $key (keys %table_paths)
{
delete $table_paths{$key} if (grep {$_ =~ /$key$/} (keys %list_paths));
}
#printing unmatched keys
print "unmatched :$_nlocation: $table_paths{$_}nn" foreach keys %table_paths;

输入

在某些/位置/表中.txt

##WHAT PATH IS_THAT,Backup
a   b/c/d   B
a   b/c/d/e  B
a   b/c/d/e/f  B
a   b/c/d/g  B

在某些/location_2/表中.txt

##WHAT PATH IS_THAT,Backup
a   b/c/d/j B

在列表中.txt

rty/b
uio/b/c
qwe/dummyName/b/c/d
asd/b/c/d/e
zxc/b/c/d/e/f
vbn/c/d/e
fgh/j/k/l

输出:

unmatched: b/c/d/g
location: some/location/table.txt
unmatched: b/c/d/j
location: some/location_2/table.txt

相关内容

  • 没有找到相关文章