Link to home
Start Free TrialLog in
Avatar of Pampa
Pampa

asked on

Hash Syntax problem

Situation:

I need to read from a file some lines.
Each line I have to include it in a Array.
Then I'am making a break and include all the array in a Hash,
so I have something like this:

Hash :  NodeA includes Array
        NodeB includes Array
        NodeC includes Array

Then I keep on going reading the file.

Then I have to access the elements of the array of each node of the hash.

My Problem is that I can´t access to the elements of the array

I must be doing something wrong.
Can anybody Help me to correct this HASH fill-in problem....

I send the instructions I'am using...


          INIT the ARRAY  
          $arraydatos=[]
         
          FILL the ARRAY
          $$arraydatos[$indice]=$date
          $indice ++

         FILL the HASH
         $Hash{$name}=$arraydatos
 
       PRINT a array element of a node
         print $Hash{$name}->[0]  

This doesn´t works....
Avatar of maneshr
maneshr

can you send your data file??
Also pl. mention which col in that file you want as the key to your HASH.

Rgds
Avatar of Pampa

ASKER

Ok I'll send you.
Sorry I can't keep the indent...

Data File
open (GRUPOS,'Grupos.txt');

$grupoant ="";
$entrar =0;
while (<GRUPOS>){
 
  $Lineagrupo =(/\[(.*?)\]/);
  if ($Lineagrupo){
     $indiceant=$indice;
     $indice=0;
     $arraydatos=[];
     $grupo = $1;          
$$arraydatos[$indice]=$grupo;          
     $indice =$indice +1;
     $entrar=1;          
  }  
if ($grupo eq $grupoant){    
   $Lineamap =(/\MAP(.*?)\n/);
   if ($Lineamap){  
      $countmap = "MAP".$1;  
$arraydatos[$indice]=$grupo;                        
      $indice =$indice +1;
  }
$Lineaiconos =(/\ICONOS(.*?)\#(.*?)\n/);  
   if ($Lineaiconos){
      $countRun = "ICORUN".  $1. "FMXPATH". $2;
      $$arraydatos[$indice]=$grupo;            
      $indice =$indice +1;
    }
}            
 else{
     if ($grupoant ne "" && $entrar==1){
         $Hash{$grupoant}=$arraydatos;
         $entrar =0;
      }                  
        $grupoant=$grupo;
 }            
}

DATAFILE:
.....Under teh word ICONOS is only one line....

[Domain Users]
MAP net use h: \\SIIFPRUEBAS\Logon /yes
MAP net use g: \\SIIFPRUEBAS\Logon /yes


ICONOS "c:\\orawin95\\bin\\f45run32.exe" # "g:\\mprincipal.fmx"  

[SNAUSERS]
MAP net use r: \\SIIFPRUEBAS\Logon /yes
MAP net use s: \\SIIFPRUEBAS\Logon /yes
ICONOS "z:\\orawin95\\bin\\f45run32.exe" # "z:\\mprincipal.fmx"  
ICONOS "2:\\orawin95\\bin\\f45run32.exe" # "2:\\mprincipal.fmx"  



#INIT the ARRAY:
my(@arraydatos);

#FILL the ARRAY:
$arraydators[$indice++]=$date;

#FILL the HASH:
$Hash{$name}=\@arraydatos;

#PRINT an array element of a node:
print $Hash{$name}->[0];


Hope this helps
  Tobias

let me understand this.

Give the data file....

[Domain Users]
MAP net use h: \\SIIFPRUEBAS\Logon /yes
MAP net use g: \\SIIFPRUEBAS\Logon /yes


ICONOS "c:\\orawin95\\bin\\f45run32.exe" # "g:\\mprincipal.fmx"  

[SNAUSERS]
MAP net use r: \\SIIFPRUEBAS\Logon /yes
MAP net use s: \\SIIFPRUEBAS\Logon /yes
ICONOS "z:\\orawin95\\bin\\f45run32.exe" # "z:\\mprincipal.fmx"  
ICONOS "2:\\orawin95\\bin\\f45run32.exe" # "2:\\mprincipal.fmx"  


You want to create a Hash with the section name (Domain Users, SNAUSERS etc..) as the key.

The value for this has will be the diff entries, under that section, properly formatted.

Based on the above assumption, i have the foll code........


=====================Grupos.txt
[Domain Users]
MAP net use h: \\SIIFPRUEBAS\Logon /yes
MAP net use g: \\SIIFPRUEBAS\Logon /yes

ICONOS "c:\\orawin95\\bin\\f45run32.exe" # "g:\\mprincipal.fmx"

[SNAUSERS]
MAP net use r: \\SIIFPRUEBAS\Logon /yes
MAP net use s: \\SIIFPRUEBAS\Logon /yes
ICONOS "z:\\orawin95\\bin\\f45run32.exe" # "z:\\mprincipal.fmx"
ICONOS "2:\\orawin95\\bin\\f45run32.exe" # "2:\\mprincipal.fmx"

=====================grupos.pl
#!/usr/bin/perl

$entry="";

open (GRUPOS,'Grupos.txt') || die $!;

while (<GRUPOS>){
  s/^\s+//g;  ##  Remove any leading white space from every line
  s/\s+$//g;  ##  Remove any trailing white space from every line

  if (/^\[(.*)\]$/){    ##  Section name found
    ##  Extract the Section name, which is also the key to the HASH
    if ($entry){
      $Hash{$Lineagrupo}=$entry;  ##  Store the items under that section in the
 Hash
      $entry="";
    }
    $Lineagrupo=$1;
  }else{  ##  An item under a section
    if (/^MAP(.*)$/){   ##  A MAP item found
      $entry.="MAP".$1."\t";
    }elsif (/^ICONOS(.*?)\#(.*?)$/){  ##  A ICONOS item found
      $entry.="ICORUN".$1."FMXPATH".$2."\t";
    }
  }
}

if ($entry){
  $Hash{$Lineagrupo}=$entry;  ##  Store the items under that section in the Has
h
  $entry="";
}

##  Now print out the hash and its values
foreach(sort keys %Hash){
  print "Section $_\n";
  @entries=split(/\t/,$Hash{$_});

  foreach(@entries){
    print "\t$_\n";
  }
  print "\n";
}

Avatar of Pampa

ASKER

Maneshr and Tobias, both of you gave me the rigth solution, but Maneshr came first, so I will give the points to MAneshr.

But first I have one more doubt Maneshr:

1) I want to print the key of the hash
2) A specific element of an SPECIFIC entry of the hash.

How should I do this (I need the Syntax)?

Thanks,
perl -e '@a=("a","b","c");@b=(4,6,8);%h=("a",[@a], "b",[@b]);print $h{"b"}[2]'
Avatar of Pampa

ASKER

The answer was almost answered by Maneshr.

So the point I will give to him.

Maneshr I saw you put all the elements of the HASH in a Lineal array to print them.
But I need to have them in separate boxes of the array so I can treat them as I want.
Can you help me modfy the last part of your code to do this?
Avatar of Pampa

ASKER

Maneshr, I saw better your code and the original problem I have I still having....

Because You didn't make a Hash wich reference different arrays, you made a HASH in wich each position have the elements concatenate as Strings.

I need TO HAVE:
Every position of teh HASH points to an Array wich the elements you put in the string.
Then I need to know how Access to them.
Can you modified your code to do this?
 
ASKER CERTIFIED SOLUTION
Avatar of maneshr
maneshr

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Pampa,

are you looking for this?

Tobias

#!/usr/local/bin/perl
my($section,%hash);
open(GROUPOS,"<groupos.txt") || die "Can't open groups.txt - $!";
while(<GROUPOS>) {
  # get rid of leading spaces, comments
  s/^\s*//;s/#.*$//;
  $section=$1,next if (/^\[([^\]]+)\]/);
  next unless (/^(\S+)\s*(.*)$/);
  push(@{$hash{$section}->{uc($1)}},$2);
}
close(GROUPOS);

foreach $section (keys %hash) {
  print "Section: $section\n";
  foreach my $subsection (keys %{$hash{$section}}) {
    print "  Subsection: $subsection\n";
    foreach my $entry (@{$hash{$section}->{$subsection}}) {
       print "   Entry: $entry\n";
    }
  }
}

Err - I thought # was a comment :-)

#!/usr/local/bin/perl
my($section);
open(GROUPOS,"<groupos.txt") || die "Can't open groups.txt - $!";
while(<GROUPOS>) {
  s/^\s*//;s/\s*$//;
  $section=$1,next if (/^\[([^\]]+)\]/);
  push(@{$hash{$section}->{MAP}},"MAP".$1) if(/^MAP(.*)$/);
  push(@{$hash{$section}->{ICONOS}},"ICORUN".$1."FMXPATH".$2) if(/^ICONOS(.*?)\#(.*?)$/);
}
close(GROUPOS);

print "Dump:\n";
foreach $section (keys %hash) {
  print "Section: $section\n";
  foreach my $subsection (keys %{$hash{$section}}) {
    print "  Subsection: $subsection\n";
    foreach my $entry (@{$hash{$section}->{$subsection}}) {
       print "   Entry: $entry\n";
    }
  }
}
print "\n\nSpecific questions:\n";
print $hash{'Domain Users'}->{MAP}->[1],"\n";
print $hash{SNAUSERS}->{ICONOS}->[0],"\n";


thoellri, your push() is the same as my initial assignment of the hash.
Think Pampa is not looking for "how it works" but for a working, ready to use, script.
Avatar of Pampa

ASKER

I accept the first correct answer I recived.