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

Hello Oh Masters of Perl Wisdom, I need a script that reads in a text file, replaces the first line and outputs another file with the new first line along with the rest of the file. In the first line I need to write out a a 6 character string that is always on the 12th line of the file at the 50th position. Here is the code I have that does everything but get that 6 character variable. I wrote some other code to get the variable, but I can't seem to get the script to loop back to the top to start writing out the whole file. I want the 6 character variable to go where the 'JF' literal goes on the $newjob line in this code...
{ $buffer = ''; $filename = ''; $line = ''; $job = ''; $temp = ''; $index_job = 0; $key = ''; $tray = ''; print LOG "$mday$mon$year $hour:$min:$sec Processing Data file, s +plitting Jobs.\n"; # Skip first line. #<INFILE>; while (<INFILE>) { $line = $_; if ($line =~ /^(\^JOB.*)\n$/i) #if the current line is a ^job +line then { $tmp = $1; #Set $tmp equal to what is in (\^JOB.*) ie: ^jo +b PATIENTLBL -c1 -zDP7P @pieces = split(/ /, $tmp); #Split-up the entire line, on +spaces, into @pieces $newjob = $pieces[0]." "."JF".$pieces[1]." ".$pieces[2]." +".$pieces[3]."\n"; #Rebuild ^job line with JF in front of jobname #print "newjob : ".$newjob; $temp = $newjob; #Assign new ^job line to $temp to create +new file(s) if ($buffer ne "") #Not first job { print LOG "$mday$mon$year $hour:$min:$sec Found: $jo +b"; $buffer_job[$index_job++] = $buffer; } $job = $temp; $buffer = $temp; }else{ $buffer .= $line; } }

Replies are listed 'Best First'.
Re: Text Processing
by arturo (Vicar) on Apr 21, 2001 at 00:48 UTC

    The biggest piece of the puzzle you need is the seek function (perldoc -f seek on your system or perlfunc:seek for a quick ref). While you can open files for both read and write access, I like to work with a scratch file. So here are the steps the way I'd do it:

    open OLDFILE, $oldfilename or die "Can't open $oldfilename: $!\n"; # get length of first line my $start_pos = length(<OLDFILE>); # now read in next 11 lines for (1..11) { $_ = <OLDFILE>; } # we've got the 12th line in $_ # nab the 6 chars starting at the 50th position of $_ my $field = substr($_, 49,6); #rewind to the beginning of the second line seek(OLDFILE, $start_pos,0); open NEWFILE, "> $oldfilename.new" or die "Can't open $oldfilename.new for write: $!\n"; print NEWFILE "STring with $field in it\n"; # now write eatch line of OLDFILE INTO NEWFILE print NEWFILE while (<OLDFILE>); close OLDFILE; close NEWFILE; rename ($oldfilename, "$oldfilename.bak") or die "Can't move $oldfilename: $!\n"; rename ("$oldfilname.new", $oldfilenme) or die "Can't create new $oldfilename: $!\n";

    Yeuch that's kinda clunky, but those are the steps.

    HTH

Re: Text Processing
by Sprad (Hermit) on Apr 21, 2001 at 00:45 UTC
    I just recently discovered some functions that are good for this sort of thing. seek() and tell(). tell(FILE) will return your current position in the file FILE, and seek(FILE, $n, 0) will send you to the location in FILE stored in $n. Use them like this:
    # open your file $top_of_file = tell(FILE); # go fetch your variable seek(FILE, $top_of_file, 0); # now you're back at the top
    They're handy in other situations, too. You can tell() any number of positions in the file, and go back to them at will. I bet there's a JAPH in that concept somewhere...

    ---
    I'm too sexy for my .sig.

      Silly ol' me forgot about tell in my response (I used that inelegant length thing). Oh well; I just wanted to register the caveat that you must read in the first line *before* you do the call to tell, otherwise you get the uninformative result 0.

        But isn't that the very beginning of the file? Or is that not where we want to be?

        ---
        I'm too sexy for my .sig.

Re: Text Processing
by Sifmole (Chaplain) on Apr 21, 2001 at 00:36 UTC
    @pieces = split(/ /, $tmp); #Split-up the entire line... $newjob = $pieces[0]." "."JF".$pieces[1]." ".$pieces[2]. " ".$pieces[3]."\n"; $temp = $newjob;
    Could probably be replaced with...
    $tmp =~ s/^([^ ]+\s+)/$1JF/;
      I need JF to be replaced by a string from the 12th line...
        Well you can still use the expression... Just replace the JF with a var that contains the string you want to put in there. I thought you already had the code to extract the string. Sorry.
Re: Text Processing
by greenFox (Vicar) on Apr 21, 2001 at 02:13 UTC
    Here is another approach not using seek. (Untested)
    open (INFILE, $infile) || die "but... $!"; open (OUTFILE, ">$outfile") || die "but... $!"; my @hold; while(<INFILE>){ if ($. < 12){ push @hold, $_; next; } if ($. == 12){ # grab some data from the 12th line # perform some funky manipulation on it print OUTFILE "new funky data from 12th line"; print OUTFILE @hold; next; } print OUTFILE $_; }

    see perlman:perlvar

    TIMTOWTDI :)

    --
    my $chainsaw = 'Perl';

Re: Text Processing
by Ixandantilus (Initiate) on Apr 21, 2001 at 06:48 UTC
    Thanks to you all!