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

I have a file that contains the following information:

Name - John filename "LKTA_mic4.cfg"; } Name - Tim filename "LKTA_mic2.cfg"; } Name - Jane filename "LKTA_mic1.cfg"; } Name - Jim filename "LKTA_mic3.cfg"; } Name - Don filename "LKTA_mic1.cfg"; } Name - Cody filename "LKTA_mic4.cfg"; }
I need to have the script search for 'LKTA' in the line.  If it contains text, serialize the number portion starting at 1 and ending at 4.  when it hits the fifth instance of 'LKTA', start back at 1 (loop until complete basically).  If it doesn't contain the string 'LKTA', simply print the line.

The desired output would be:

Name - John filename "LKTA_mic1.cfg"; } Name - Tim filename "LKTA_mic2.cfg"; } Name - Jane filename "LKTA_mic3.cfg"; } Name - Jim filename "LKTA_mic4.cfg"; } Name - Don filename "LKTA_mic1.cfg"; } Name - Cody filename "LKTA_mic2.cfg"; }
My knowledge of Perl is limited, and the scripts I have been trying to write are a dismal failure.  I think the best method for this would be to delete the number, and then just run a serializing loop printing 1 through 4. Any help you have to offer would be very nice of you.

Replies are listed 'Best First'.
Re: serialze text in a file
by toolic (Bishop) on Jul 07, 2009 at 17:04 UTC
    Your algorithm sounds right. Here is one way to do it:
    use strict; use warnings; my $i = 1; while (<DATA>) { if (s/(LKTA_mic)\d/$1$i/) { $i = ($i == 4) ? 1 : $i + 1; } print; } __DATA__ Name - John filename "LKTA_mic4.cfg"; } Name - Tim filename "LKTA_mic2.cfg"; } Name - Jane filename "LKTA_mic1.cfg"; } Name - Jim filename "LKTA_mic3.cfg"; } Name - Don filename "LKTA_mic1.cfg"; } Name - Cody filename "LKTA_mic4.cfg"; }

    prints out:

    Name - John filename "LKTA_mic1.cfg"; } Name - Tim filename "LKTA_mic2.cfg"; } Name - Jane filename "LKTA_mic3.cfg"; } Name - Jim filename "LKTA_mic4.cfg"; } Name - Don filename "LKTA_mic1.cfg"; } Name - Cody filename "LKTA_mic2.cfg"; }

    Update: changed to use capturing in regex.

    Also, Search and replace

      Hey, I am learning regex now, it is like head-hammering at someplaces hehe...anyways I wanted to ask you, in this line you wrote,
      if(s/(LKTA_mic)\d/$1$i/)
      ok, I see that you are using backreferences to (LKTA_mic), but the way you used the variable $i, I mean, if these files were different, each one of them was a different identity in DATA, and each one of them had its unique number though the arrangement was not serial still, would they be physically re-arranged or ...according to what I could elicit here, they are merely being renamed instead? so the DATA file
      Name - John filename "LKTA_mic4.cfg"; }
      would be renamed to
      Name - John filename "LKTA_mic1.cfg"; }
      with contents intact and so on...?
      ##excuse my ignorance but slight not my attempts to learn##
        Yes, my code does a simple text substitution, replacing a single digit (0 through 9) with the value in the $i variable.
Re: serialze text in a file
by BioLion (Curate) on Jul 07, 2009 at 17:20 UTC

    I might be missing the point, but it sounds like you just want to read in all the names, then print them out again with a modified filename?

    #!usr/bin/perl use strict; use warnings; my $fpath = shift @ARGV; open (my $fh, '<', $fpath) || die "Failed to open $fpath : $!"; my $matches = 0; ## counter for how many matches we have made while (<$fh>){ if ( /^(filename\s\"LKTA_mic) ## find start of name and capture it \d+ ## number bit - don't capture (\.cfg\"\;\s\}$) ## end bit - capture /gx ){ ## print out line with number modified based on how many matches w +e have seen print "$1".(($matches % 4) + 1)."$2\n"; ## increment match counter ++$matches; } else { ## didn't match so pump it straight out unmodified print $line; } }; close $fh || die "Failed to close $fpath : $!";

    This just prints out to STDOUT, but it is easy enough to put it somewhere else!
    You will find more elegant/short ways of doing this but i wanted to be clear...
    Hope this helps!

    Update Actually commenting the comments in the regex... and getting the filenumbers right

    Just a something something...