in reply to Re: Parsing a file line by line until a certain indice in array
in thread Parsing a file line by line until a certain indice in array

I think the main problem is that where you have:
    if ($volume =~ $vol_to_parse) {
you really should have:
    if ($volume =~ /$vol_to_parse/) {
since it's a regular expression.

A 'naked string' used as a regex will work just as well with the  =~ and  !~ binding operators as enclosing the string in  // delimiters, as shown by the example below.

>perl -wMstrict -le "my $rx = 'x\dy'; for my $str (qw(xxy x23y x4y xy)) { print qq{match '$str'} if $str =~ $rx; print qq{no match '$str'} if $str !~ $rx; } " no match 'xxy' no match 'x23y' match 'x4y' no match 'xy'

The problem with using a string in that way (or within  // delimiters) is that Perl is forced to re-compile the regex each time it is encountered (IIRC). This probably does not matter in a short script processing a short file, but it may matter if the file is 100,000,000 lines long!

The re-compilation problem can be avoided by using the  /o 'compile once' regex modifier:
    if ($volume =~ /$vol_to_parse/o) {

However, the preferred method with modern Perl is to compile a regex object with the  qr operator. With such an object, you never have to worry about re-compilation unless you really need to do it.
    my $rx_vol_to_parse = qr{ \Q$vol_to_parse\E }xms;
    if ($volume =~ $rx_vol_to_parse) {
In addition (and probably more importantly), if you use a regex object you don't have to worry about differences in interpolation between single- and double-quoted strings and in regexes, and regex metacharacters. For instance, consider the difference between the behavior of
    my $rx = 'x\dy';
and
    my $rx = "x\dy";
in the command-line example given above.

As mentioned above, the difference between the two approaches (i.e., regex object vs. naked string) is probably not significant in this particular situation, but it's always best to try to develop good programming habits right from the beginning.

Replies are listed 'Best First'.
Re^3: Parsing a file line by line until a certain indice in array
by sluggo (Novice) on Sep 06, 2009 at 19:03 UTC

    Thank you very much for the help guys. All my questions thus far have been answered and then some.

    It completely works the way I want it to, but I am curious, what if some lines had, lets say a word in the beginning of the line. That I did not want to return with the rest of the line, for instance, I have one line with the word DISKUSED in the front.

    The normal structure of the lines I am returning look like this:

    DISKUSED OK - /vol/hello/ - total: 83886080 Kb - used 519800 Kb (1%) - + free: 83366280 Kb /vol/john/.snapshot - total: 0 Kb - used 30971856 Kb (0%) - free: 0 Kb /vol/bill/ - total: 20132660 Kb - used 7178128 Kb (36%) - free: 129545 +32 Kb /vol/ted/ - total: 52428800 Kb - used 4137924 Kb (8%) - free: 48290876 + Kb

    There is only one instance where there will be something before the volume name in my file. I just want to be prepared for that, but at the same time I am curious as to how to get passed that if it occurred multiple times.

    I guess what I am trying to ask is, as opposed to returning the entire line, how can I manipulate the STDOUT to be printing everything from $vol_to_parse to end of line?

    And secondly, is that the right way I should be thinking for a situation like this in perl? Or is there some kind of reverse-chomp-type modifier.

    Once again, any and all help is greatly appreciated.

    Thank you,

    Sluggo

      If I understand your question correctly, you might try something like:
      my $vol_to_parse = qr{ /what/ever }xms; my $line = get_a_line_somehow(); if ($line =~ m{ ($vol_to_parse .*) }xms) { print "$1 \n"; }