http://qs321.pair.com?node_id=652566


in reply to Newbie: uses/limits of perl in editing files

Welcome to the monastery. From the task description I'd say perl is very well suited. I'll give you an example for a program that roughly does what you describe

#!/usr/bin/perl use warnings; use strict; my $filename = "whateveryourfileiscalled.txt"; my $newfile = "whateveryouwantthechangedfiletobecalled.txt"; open (my $rfh,"<",$filename) or die "Can't open file $filename : $!"; open (my $wfh,">",$newfile) or die "Can't open file $newfile : $!"; while (my $line = <$rfh>) { if ($line =~ m/^HEADER/) { chomp $line; my $number = 42; # change to whatever number you want to use $line .= $number."\n"; } if ($line =~ m/^REMARK/) { print {$wfh} "Extra line\n" # Change to whatever extra line yo +u want } print {$wfh} $line; } close $rfh or die "Can't close $filename : $!"; close $wfh or die "Can't close $newfile : $!";
Or you could do this in a perl oneliner (which will change the original file):
perl -pi -e 'chomp;s/^(HEADER.*)$/${1}42/;s/^(REMARK.*)$/Extra line\n$ +1/;$_.="\n"' whateveryourfileiscalled.txt
Caveat: Both of these are for systems where the line ending is "\n" (i.e. not Windows), adjust appropriately for other OSes. Update: the caveat is not actually correct, as pointed out by naikonta and wfsp, except possibly for the case outlined by Sixtease, also fixed in his update. Thanks to all of you.

All dogma is stupid.

Replies are listed 'Best First'.
Re^2: Newbie: uses/limits of perl in editing files
by Sixtease (Friar) on Nov 23, 2007 at 14:13 UTC
    Wow, I didn't know the print {$wfh} $line; construct. Does that disambiguate $wfh to be interpreted as a filehandle?

      Yes; because the "filehandle argument slot" (for lack of a better name) has to be a simple scalar value or a BLOCK. While it's superfluous in this particular case the block form is useful if you (for instance) have a hash of filehandles and want to use print { $handles->{$somekey} } "Yadda yadda yadda.\n"; directly rather than pulling it out into a tmp variable. The docs for print cover this.

      Yep, I picked that up from thedamians Perl Best Practices (a must-read for every Perl programmer IMO). As Fletch rightly points out, it's not necessary in this case, but I just use it wherever I print to a filehandle (easier to do than figure out what's wrong if I ever forget it :-)


      All dogma is stupid.
Re^2: Newbie: uses/limits of perl in editing files
by naikonta (Curate) on Nov 23, 2007 at 15:33 UTC
    Caveat: Both of these are for systems where the line ending is "\n" (i.e. not Windows), adjust appropriately for other OSes.
    I see no caveat in your example regarding \n. This character is just the Perl internal representative of a thing that constitutes line ending. So it will be whatever the underlying OSes (perl is run on) actually use to terminate lines. See how newlines are addressed in perlport.

    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

Re^2: Newbie: uses/limits of perl in editing files
by wherethewild (Novice) on Nov 23, 2007 at 14:24 UTC
    That's it! Wow, let's see how I go at adjusting it all for everything else I have to do to it. The weekend shall be fun.

    One problem though, and I guess it has something to do with the \n point you made at the end. Now I have <cr> appearing at the end of every line. I'm sitting on a Linux workstation running RedHat if that is at all helpful (I DID say I know nothing about this!)

    cheers
    wherethewild

      Here's my guess:

      Your file has Windows newlines (cr/lf), which your editor/viewer can deal with and shows it correctly. Then you add unix newlines (lf) on the lines you edit. Now there are mixed cr/lf and lf newlines, which confuses the editor and it shows the cr characters.

      If I'm correct, then I recommend either preprocess the file with the dos2unix tool or address this in the perl script itself

      update: The modified while loop could look like this:

      while (my $line = <$rfh>) { chomp $line; if ($line =~ m/^HEADER/) { my $number = 42; # change to whatever number you want to use $line .= $number; } if ($line =~ m/^REMARK/) { print {$wfh} "Extra line\n" # Change to whatever extra line yo +u want } print {$wfh} $line, "\n"; }
        unfortunately, still a problem. Thanks for all the help so far though, it's certainly moving me forward much faster than if I was left to beat my head against the screen alone!