Reputation: 181
I have a Deep Directory Structure with the following format
/intf1/syst1/some1 /intf3/syst4/some111 /intf1/syst2/some2 /intf2/syst1/some1 /intf2/syst3/some9 /intf4/syst2/sdsds
Need the output, in the format"
syst1 syst2 syst3 syst4 intf1 x x intf2 x x intf3 x intf4 x
How can I do this in Perl?
NOTE: intf1... intfn need to be sorted Alphanumerically, similarly syst1... systn the same
Upvotes: 1
Views: 121
Reputation: 118138
While @DVK's answer is the way I would go for a general problem of this sort, I am wondering if your instructor meant for you use arrays and regular expressions to solve this as you clearly have a matrix.
The code is terse and uncommented on purpose.
#!/usr/bin/perl
use strict; use warnings;
my @matrix;
my ($i_max, $j_max) = (0, 0);
while ( my $path = <DATA> ) {
next unless $path =~ m{/intf([0-9])/syst([0-9])/\w+};
my ($i, $j) = map $_ - 1, $1, $2;
$matrix[$i][$j] = 1;
$i_max = $i if $i > $i_max;
$j_max = $j if $j > $j_max;
}
print_row(['' => map "syst$_", 1 .. $j_max + 1]);
for my $i ( 0 .. $i_max ) {
print_row([
'intf' . ($i + 1), map {
my $v = $matrix[$i][$_];
defined($v) ? 'x' : '';
} 0 .. $j_max
]);
}
sub print_row { print join("\t", @{ $_[0] }), "\n" }
__DATA__
/intf1/syst1/some1
/intf3/syst4/some111
/intf1/syst2/some2
/intf2/syst1/some1
/intf2/syst3/some9
/intf4/syst2/sdsds
Upvotes: 0
Reputation: 129413
Create hash of hashrefs to store the matrix you want (call it %files
)
Create a hash to store the list of syst
names (call it %subdirs
. Should be a has instead of array to ensure uniqueness).
Use glob()
to obtain a list of files
Use File::Spec->splitpath()
to split each path in the list into directory components and filename.
Put value 1
into hash-of-hashrefs %files
with keys determined by first and second directory components from previous step (e.g. $files{$dir1}->{$dir2} = 1;
.
Also, put value of 1
into the %subdirs
hash for a subdirectory.
When done looping over the list of files, print results
a. Run a loop over sorted list of keys for %subdirs
hash. For each value, print that value followed by a space. Then at the end print newline.
b. Run a loop over sorted list of keys for %files
hash-of-hashrefs. For each key $dir1
:
i. Print the key value, followed by as many spaces as needed to ensure alignment. How to do that is left as excercise for the reader.
ii. Run a loop over sorted list of keys for %subdirs
hash. For each key $dir2
:
- Print an X if `$files{$dir1}->{$dfir2}` is true, and print 1 space otherwise.
- print N spaces where N is a length of the directory `$dir2`
iii. Print newline
Upvotes: 2