in reply to Re^2: very new to perl; suggestions for porting this shell script to perl?
in thread very new to perl; suggestions for porting this shell script to perl?
Here is a solution, but you should probably check it to see if it meets your specifications.
#!/usr/bin/perl use strict; use warnings; my @files = glob "/usr/share/applications/*.desktop"; my $regex = join "|", qw/ Audio Graphics Network Settings System Utili +ty /; my %data; FILE: for my $file (@files) { open my $fh, "<", $file or die "Unable to open $file (for reading) +. $!"; my ($category, $name, $exec); while (<$fh>) { if(/^Categories=.*?\b($regex)\b/) { $category ||= $1; # sets cat for first time only (each fil +e) } elsif (/^Name=(.+)$/) { $name ||= $1; # sets name first time only (each file) } elsif (/^Exec=(\S+)/) { $exec ||= $1; # sets exec first time only (each file) } } close $fh or die "Unable to close $file. $!"; for ($category, $name, $exec) { if (! defined) { warn "$file missing category or name or exec.\n"; # skip the 'push' below and go to the label 'FILE:' next FILE; } } push @{ $data{ $category } }, {name => $name, exec => $exec}; } for my $category (keys %data) { print "Submenu = \"$category\" {\n"; my @recs = @{ $data{ $category } }; for my $href ( @recs ) { # hash reference print " Entry = \"$href->{name}\" { Actions = \"$href->{ex +ec}\" }\n"; } print "}\n"; }
Notice how all the variables are declared with my. Declaring variables this way helps catch spelling errors and also limits the scope to the innermost containing block. This property is handy and can be seen in the declaration of my ($category, $name, $exec)
Every time the for loop starts a new iteration, (with a new file), it gets a fresh copy of 'undefined' variables. Then, later on they are assigned to, ($category ||= $1;). The first time a valid match is made, an assignment will happen. If there are more than 1 instance of name or exec (as you noted in your post), they will be ignored. This is because any of the three already has the first match assigned to it.
The data is stored in the %data hash (which is then printed out when the loop terminates).
The glob function does wildcard expansion and returns all the matching files. (gimp.desktop and all other files with the .desktop extension).
There are many other Perl idioms here and if you have questions about just why a certain piece is written the way it is, just ask.
If you plan on using Perl now on, it would be probably helpful to read a book such as Learning Perl witch is a good intro to Perl or Programming Perl which is larger but a good reference book.