Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

It is with great reluctance (and hope) that I post such a basic problem.

So far I have only been able to find bits and pieces on this and when I put the bits together they do not work. Maybe I am going in the wrong direction.

I want to count several strings of text in a file (security.txt) and output the counts with a brief description of each. I have tried specifying the descriptions (name) and the strings (exe) in the array within the perl script. I can open the file to search ok, but the counting/output doesn't work. It seems to count every line in the file. The strings are not on their own lines in security.txt.

The goal is to see something like:

Name: Catalog Count:2 Name: Crime Count:1
Yes I am a newb, so if anyone can point me in the right direction I'd sure appreciate it. TIA, Sam
print "\nSEARCHING...\n"; open (FILE, "security.txt"); print "\n"; ###### Define names and their file paths ###### %exe = ( "Catalog", 'C:\Program Files\Internet Explorer\IEXPLORE.EXE', "Crime", 'D:\crime\Reader\AcroRd32.exe'); ###### Try to count the occurance of file paths ###### $count=0; while(<FILE>) { chomp; #if ($_ = (values %exe)) { $count++; } ###### print names and counts ####### foreach $key (keys %exe) { print "Name: $key\t Count: $count\n"; } close(FILE); print "\nDONE.\n";

Replies are listed 'Best First'.
Re: Help - Counting text - Associative Array?
by matija (Priest) on Mar 19, 2004 at 18:46 UTC
    Ugh. You didn't say if the values appear on the lines of the file by themselves, or if they are contained inside a larger string.

    Also, you want to count several things, but you have your count as a single scalar value. That's not going to work.

    If the values appear alone, you could do something like

    while (<FILE>) { chomp; foreach $key (keys %exe) { $count{$_}++ if ($_ eq $key); } } foreach $key (keys %exe) { print "Name:$key\t Count:$count{$key}\n"; }
    Note that I've made count into a hash with the same keys as %exe, and that I've exchanged == (numeric equality) with eq (string equality).

    If the strings you're looking for aren't the only thing in each line you read, you'd better use index or a regex to find them - string comparison won't work.

      Ok I tried your code and of course you are right. I changed it so it will return the count of THE VALUES of the array in the file, but the strings have to be on their own lines (as you said). Since the string we're using is the VALUE, it prints the VALUE not the KEY at the end.

      I guess I will have to research regex and see what I can do. Just for grins I've attached the code and result. To test it I had to create a file with the exe strings on their own lines.

      Thanks again for the help.

      Code:

      open (FILE, "security2.txt"); print "\n"; %exe = ( "Catalog", 'C:\Program Files\Internet Explorer\IEXPLORE.EXE', + "Crime", 'D:\crime\Reader\AcroRd32.exe'); while (<FILE>) { chomp; foreach $value (values %exe) { $count{$_}++ if ($_ eq $value); } } foreach $value (values %exe) { print "Name:$value\t Count:$count{$value}\n"; } close(FILE);

      Result:

      Name: C:\Program Files\Internet Explorer\IEXPLORE.EXE Count: 2 Name: D:\crime\Reader\AcroRd32.exe Count: 1

Re: Help - Counting text - Associative Array?
by dragonchild (Archbishop) on Mar 19, 2004 at 18:43 UTC
    It would help to see an example of security.txt.

    Your line  if ($_ = (values %exe)) { is wrong. Very wrong.

    1. You're using the assignment operator, not the equality operator.
    2. It sounds like your file is a list of numbers, cause you're comparing the value to the number of values in %exe

    Not seeing the textfile, we really can't help more.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: Help - Counting text - Associative Array?
by NetWallah (Canon) on Mar 19, 2004 at 18:46 UTC
    The data structure you are looking for is something like this:
    my %exe = ( "Catalog" => {name=>'C:\Program Files\Internet Explorer\IE +XPLORE.EXE', count=> 0}, "Crime" => {name=> 'D:\crime\Reader\AcroRd32.exe', count=>0} ); # You don't need to do #if ($_ = (values %exe)) # The value of $Loop_Variable should be from the file you read #Then you can increment using $exe{$Loop_Variable}{count}++; # Finally, print using $exe{$Loop_Variable}{count};

    Offense, like beauty, is in the eye of the beholder, and a fantasy.
    By guaranteeing freedom of expression, the First Amendment also guarntees offense.

Re: Help - Counting text - Associative Array? (I was Annon Monk)
by Mr_Lowry (Initiate) on Mar 19, 2004 at 19:25 UTC
    Thanks for your fast replies, oh wise ones. The values don't appear on lines by themselves (I think I did mention that). Anyway here's an example of security.txt:

    3/15/2004,3:01:18 PM,Security,Success Audit,Object Access ,560,SERVER\ +refterm,SERVER,"Object Open: Object Server: Security Object Type: File Object Name: C:\Program Files\Internet Explorer\IEXPLORE.EXE New Handle ID: 536 Operation ID: {0,178316546} 3/15/2004,1:57:28 PM,Security,Success Audit,Object Access ,560,SERVER\ +Anon000,SERVER,"Object Open: Object Server: Security Object Type: File Object Name: D:\crime\Reader\AcroRd32.exe New Handle ID: 592 Operation ID: {0,177426959}
    Just let me say that I have no formal training with Perl (intentionally sounding like William Hung). I had to find a work around for auditing Citrix database publication and suspected that Perl could help. So I looked at a bunch of library books and searched the net which led me to you!

    Sincere thanks for your help.

    Sam Lowry

      Hi Sam. This additional information helps, but what output do you want from the above example? Say you're searching for the number of times 'catalog' and 'crime' appear in security.txt, do you want zero for the former and 2 for the latter (which is the number of times these words appear in the section of the file you have shown us)? That would be pretty easy (but you would have to think about whether you want to include 'Crime' (capital first letter), 'crimes' (plural)... and then about how to exclude eg 'Crimean').

      Or do you perchance want to open the files in the 'Object Name' field and search these for the words in question, which is not so easy, but eminently feasible (and note that the 'crimes/Crime/Crimean' issue remains)?

      dave

        HI Dave-

        You ask good questions. Disregard my earlier code because it was using the wrong variable to search with (I think that's correct?)

        What I am wanting is to find out how many times the long "exe" strings appear in a file. Then print each result with a name for the string rather than the string itself. Eg:

        C:\Program Files\Internet Explorer\IEXPLORE.EXE

        in:

        3/15/2004,2:29:31 PM,Security,Success Audit,Object Access ,560,SERVER\ +refterm,SERVER,"Object Open: Object Server: Security Object Type: File Object Name: C:\Program Files\Internet Explorer\IEXPLORE.EXE New Handle ID: 548 Operation ID: {0,178005108}

        Result:

        Name: Explorer Count: 1

        It seems I was walking down the wrong path and will have to use regex (which I have not yet read about, in all honesty) to search for the exe string within each line of text. The 'crime', 'crimean' issue is not a problem because there are no variants of the strings I'd be counting. There are MANY paragraphs like the one above in the file to be searched.

        If you have any ideas what this code might look like feel free to offer it :-) I will learn as much on my own in the meantime!

        Regards,

        Sam