Perl extract number from file & write to file

I have 1 file that has elements as follows. Also the CVR(10) and the word "SAUCE" only appear once in the file so maybe a grep command would work?

file1

CVR( 9) =   0.385E+05,  ! VEHICLE        
CVR(10) =   0.246E+05,  ! SAUCE
CVR(11) =   0.162E+03,  ! VEHICLE  

I need to extract the "0.246E+05" value for the following code. The file

#!/usr/local/bin/perl
use strict;
use warnings;
 
my $header = "Unnom_";
 
my @va = [111 222 333 444 555 666 777 888];
my @ma = [1 2 3 4 5 5a 6 7 8];
 
my $v;
my $m;
 
foreach $v (@va) {
  foreach $m (@ma) {
 
(need to get this value from file1 ex. 0.246E+05);
$extractedvalue =  (get number from /data/$m/$v/Nom_$v_$m_PUNCH)
 
system ("sed '2,10d' $m/$v/Nom_$v.ol.$m.input > $m/$v/$header$v.ol.$m.input"); #this creates a new file that has the first 2 lines of the $m/$v/Nom_$v.ol.$m.input file
 
# maybe a better way to do it would be to add this line to the added text (below) and remove the system sed command
P$WHAT PATH = '/data/$v.ol.$m.input', $
 
 
(need to add the following lines of text to the bottom of $m/$v/$header$v.ol.$m.input);
cat "
OBJECT    = A, B,   C, D, 1E+3,\n
CV(10) =  { PRM(5) = -1.0,}, \n
CVR(10)=   $extractedvalue,\n
$
"
>> $m/$v/$header$v.ol.$m.input #will this create this file if it doesn't exist? Can I create them above if the sed command is deleted?"
}
}

Thanks in advance, let me know if I poorly explained something or more info is needed.

I have been looking at your problem for a while now -- and I have no idea what you are trying to accomplish. Can you please explain? And what function is "sed" providing?

1 Like
 
$ perl -lane 'if ($_=~/SAUCE/){$F[2]=~s/,//;print $F[2]}' inputfile
0.246E+05

1 Like

what itkamaraj said is close to correct.

I need to extract the "0.246E+05" value from the first file (File1)

I then need to input this value into a newly created file with some other stuff.

For example file two should read:

Blah blah random text
 
random $text that has $$variables in it but I need to just be text
 
the above line should literally read "$text" and "$variables"
 
other $random text that i $need to evaluate variables
 
the above line should convert $random and $need to their respective values example 5 and 51
 
The variable $extracted_number - this number needs to be 0.246E+05

I don't quite understand the program in your first post, but the following Perl program might be able to help you out -

$
$
$ # Show the content of the file "file1". We'll make use of the fact that "CVR(10)" and "SAUCE"
$ # appear only once in the file.
$
$ cat file1
CVR( 9) =   0.385E+05,  ! VEHICLE
CVR(10) =   0.246E+05,  ! SAUCE
CVR(11) =   0.162E+03,  ! VEHICLE
$
$
$ # Show the Perl program
$
$ cat -n file1.pl
     1  #!perl -w
     2  use strict;
     3
     4  my $random = 5;
     5  my $need = 51;
     6  my $extracted_number;
     7  my $file = "file1";
     8
     9  # read the value of $extracted_number from "file1"
    10  open (FH, "<", $file) or die "Can't open $file for reading: $!";
    11  while (<FH>) {
    12    if (/^CVR\(10\)\s*=\s*(.*?),.*?SAUCE$/) {
    13      $extracted_number = $1;
    14      last;
    15    }
    16  }
    17  close (FH) or die "Can't close $file: $!";
    18
    19  # We have read the value of $extracted_number now; it will be used
    20  # while printing the string below
    21  my $str = <<"EOF";
    22  Blah blah random text
    23  random \$text that has \$\$variables in it but I need to just be text
    24  the above line should literally read "\$text" and "\$variables"
    25  other $random text that i $need to evaluate variables
    26  the above line should convert \$random and \$need to their respective values example 5 and 51
    27  The variable $extracted_number - this number needs to be 0.246E+05
    28  EOF
    29
    30  print $str;
$
$
$ # Execute the Perl program
$
$ perl file1.pl
Blah blah random text
random $text that has $$variables in it but I need to just be text
the above line should literally read "$text" and "$variables"
other 5 text that i 51 to evaluate variables
the above line should convert $random and $need to their respective values example 5 and 51
The variable 0.246E+05 - this number needs to be 0.246E+05
$
$
$

tyler_durden

1 Like

yea! that looks great, I don't understand this line:

if (/^CVR\(10\)\s*=\s*(.*?),.*?SAUCE$/)

I understand that it is looking for CVR(10) and SAUCE, is there some documentation to explain all the '' \?*,./ '' business? looks like gibberish to me.

Anyway works great that's what I needed, the "EOF" is quite useful

Here's a breakup of the entire regular expression -

/^CVR\(10\)\s*=\s*(.*?),.*?SAUCE$/ =>
 
See if the current line matches the regular expression that:
 
^        : has at the beginning
CVF      : the characters "C", "V", "R", followed by
\(       : an open-parenthesis character (the escape character is necessary because we want Perl to consider its literal value)
10       : followed by the characters "1", "0", followed by
\)       : a close-parenthesis character (escaping is necessary because we want Perl to consider its literal value)
\s*      : followed by 0 or more occurrences of whitespace characters
=        : followed by the "=" character
\s*      : followed by 0 or more occurrences of whitespace characters
(.*?),   : followed by the shortest continuous sequence of characters that ends with
        the comma character (","); group and capture this shortest continuous
        sequence of characters in a variable called "$1". This "grouping and
        capturing" is achieved by the parentheses; note that they are not
        escaped here, because we want Perl to consider their special (and not literal) values here
.*?S     : followed by shortest continuous sequence of characters that is followed by the character "S"
AUCE     : followed by the characters "A", "U", "C", "E"
$        : thereby reaching the end of the line

If the line does not match the regular expression, the "if" condition is false and we go to the next line.
If the line does match the regular expression, then we copy the value in "$1" to "$extracted_value" and stop processing the file (that is achieved by the "last" statement).
Since the CVR, SAUCE exists in the file only once, we don't spend time unnecessarily going through the remainder of the file once we find the extracted value. Imagine what would happen if the file had 100 million lines and the CVR, SAUCE was the 1st or 2nd line.

The "\?,./ business" is ".?" really, and it means "non-greedy/lazy quantifier". It's a part of the powerful tool called "regular expressions" and you'll inevitably encounter it while studying regular expressions. The Web and the world of books abound in information about regular expressions, and few that come to mind are as follows.

(1)  The most well-known book on regexes is this one:
Mastering Regular Expressions, 3rd Ed by Jeffrey Friedl - 
Chapter 3: Overview of Regular Expressions Features and Flavors, Section "Lazy Quantifiers"
Chapter 4: The Mechanics of Expression Processing - entire chapter provides detailed information of backtracking, greediness and laziness
 
(2)  Jan Goyvaerts, the author of "Regular Expressions Cookbook", has a website on regular expressions, and he explains greediness/laziness over there:
http://www.regular-expressions.info/repeat.html
 
(3)  The online Perl documentation has a really good tutorial on regexes. The section "Matching Repetitions" explains this concept:
http://perldoc.perl.org/perlretut.html#Matching-repetitions

tyler_durden