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

Hi,
My program asks the user to enter the name of the file and the parameter to be changed in that file from the command line.
$ perl comm.pl -f test-file -p <new value>

The test-file contents are of the form :

<PROP GUID="471138786526914052" EXPR="≪E The_Rounding_Unit=&Quot;1e-16&Quot; Absolute_Error_Tolerance=&Quot;1e-15&Quot; /&Gt";"/>

Iam posting a part of the code which replaces the old value 1e-16 (which is stored in this form &Quot;1e-16&Quot;) with the <new value> entered by the user and then renames the file with the timestamp. I can't figure out where iam going wrong. Does the command line accept more than 2 switches with values ? i have used Getopt::Long module. Please help me out.
if ($var{file}) #the test-file name entered by user { my $fname=$var{file}; unless ($fname) { die ("No file specified.\n"); } unless (-e $fname) { die ("File does not exist.\n");} my $line; open (INFO,"$fname") or die ("Cannot open .. $!\n"); while (<INFO>) { $line=<INFO>; } close INFO; my @new2; if($var{param}) { list_param($var{param}); } if($var{the}) { list_the($var{the}); } sub list_param($) { if ($line =~ m:Absolute_Error_Tolerance=&quot:) { @new2=split(/\&quot;/,$line); $line=~s/$new2[1]/$G{param}/; } } sub list_the($) { if ($line =~ m:The_Rounding_Unit=&quot:) { @new2=split(/\&quot;/,$line); $line=~s/$new2[1]/$G{the}/; } } my $timestamp = strftime("%m/%d/%Y_", localtime((stat($var{file}))[9]) +); my $file2=$timestamp.$var{file}; rename ($var{file},$file2) or warn "***\n"; }

Replies are listed 'Best First'.
Re: using command line switches to edit file
by physi (Friar) on Feb 13, 2006 at 12:17 UTC
    Hmm, don't really understand what you are doing there, but:
    while (<INFO>) { $line=<INFO>; } close INFO; my @new2; if($var{param}) { list_param($var{param}); } if($var{the}) { list_the($var{the}); }
    You read in the whole file, and do nothing, but overwrite your $line. After theat you call yout sub's with the $line, which now contains only the last line of your inputfile. Maybe you should try to put the sub-calls into the while loop!? And if you want to replace everytime the same, than this maybe will work to:
    perl -p -e 's/yourstring/yournewstring/g' inputfile > outputfile
    But that might not that flexible as you need...
    -----------------------------------
    --the good, the bad and the physi--
    -----------------------------------
    
      The test-file contents are of the form :

      <PROP GUID="471138786526914052" EXPR="≪E The_Rounding_Unit=&Quot;1e-16&Quot; Absolute_Error_Tolerance=&Quot;1e-15&Quot; /&Gt";"/>

      How do i extract the numerical values (in bold) from the above fileformat? I need to substitute it with the user input from the command line.
      while (<INFO>) { @line=<INFO>; #will this help ? my @new2; if($var{param}) { list_param($var{param}); } if($var{the}) { list_the($var{the}); } sub list_param($) { if ($line =~ m:Absolute_Error_Tolerance=&quot:) { $line=$line1; @new2=split(/\&quot;/,$line1); $line1=~s/$new2[1]/$G{param}/; } }
        @line=<INFO>; #will this help ?
        Not at all. That construct will read the whole file into an array lines. That's not what you want here. Have a look at this code.
        my $file = $ARGV[0]; my $repl = $ARGV[1]; open INFO, "<", $file or die $!; while (<INFO>) { s/(Absolute_Error_Tolerance=&Quot;)1e-15(&Quot)/$1$repl$2/; print; } close INFO;
        That can be easily made into a one-liner:
        perl -n -e "s/(Absolute_Error_Tolerance=&Quot;)1e-15(&Quot)/$1$ARGV[0] +$2/; print;" filename
        just this doesn't work. You cannot pass additional variables into an -e "code" statement. However, you avoid problem by putting that line into a shell script or batchfile (here windows batchfile, as i have no idea of shell scripts).
        @echo off perl -n -e "s/(Absolute_Error_Tolerance=&Quot;)1e-15(&Quot)/$1%2$2/; p +rint;" %1
        So you can then call that file using
        batchfilename datafile replacement
        Note: The %1 and %2 are no perl hashes but variables from the shell. They get substituted by the command line values before! the script is run.


        holli, /regexed monk/