Bogdan Jeler
Bogdan Jeler

Reputation: 3

Parse text file in Perl and get a specific string

I have a branch_properties.txt file located in my $ENV{"buildPath"} which contains the string TEST_SEQUENCE=Basic or TEST_SEQUENCE=Extended.

I need to take the value after the TEST_SEQUENCE and put it in a variable .

sub GetValueForTestSequenceSplit {

  my $filePath    = $ENV{"buildPath"} . "\\" . "branch_properties.txt";
  my $fileContent = "";

  open(my $fileHandle, "<", $filePath)
      or die("Cannot open '" . $filePath . "' for reading! " . $! . "!");

  while (my $line = <$fileHandle>) {
    chomp $line;

    my @strings = $line =~ /sequence/;

    foreach my $s (@strings) {
      print $s;
    }
  }

  close($fileHandle);
}

Where do I get wrong? The console line output in Jenkins shows nothing.

Upvotes: 0

Views: 789

Answers (2)

David W.
David W.

Reputation: 107040

A few things:

  • Use File::Spec to build the full name of your branch_properties.txt file. The \\ won't work on Unix systems.
  • Verify that $ENV{BuildPath} is a valid directory by using the -d test.
  • I'm trying to understand your question and the program you give. I can't see how you're looking for a particular line, and then pulling out the value you want.
  • What do you mean "console line output in Jenkins shows nothing"? Do you mean that Jenkins isn't building? That you see Jenkins doing stuff, but you don't see any output when this runs? Can you add a few warn statements to print out where you are? Is Jenkins saying the build failed?

Here's your program with a few revisions:

sub GetValueForTestSequenceSplit {

    use File::Spec;

    if ( not -d $ENV{buildPath} ) {
       die qq(Directory "$ENV{BuildPath}" doesn't exist);
    }

    my $filePath = File::Spec->join( $ENV{buildPath},
        branch_properties.txt";

    open( my $fileHandle, "<", $filePath )
       or die qq(Cannot open $filePath for reading! $!);  # 1.

    my $test_sequence_value;                              # 2.
    while( my $line = <$fileHandle> ) {
        chomp $line;
        next unless $line =~ /^\s*TEST_SEQUENCE\s*=\s*(.*)\s*/; # 3.
        $test_sequence_value = $1;
        last;
    }
    close $fileHandle;
    if ( defined $test_sequence_value ) {                 # 4.
        # Whatever you do if you find that value...
        return $test_sequence_value;
    }
    else {
        # Whatever you do if the value isn't found...
        return;
    }

And the notes from above:

  1. Perl can interpolate scalar variable values. This makes it much easier to read what you're printing. Also, you can use qq(...) instead of standard double quotes. This makes it easier to use quotes inside your strings. Less interpolation is needed and no back quoting.
  2. I wasn't sure what $fileContent was for. However, you don't have to set a value when you declare a variable if it has no value. In fact, it's better not to. This way, if the value isn't set, you can detect it. I use $test_sequence_value to hold the value of whatever Test Sequence is set to. It is now custom to use underscores and lowercase letters in variable names in Perl for readability rather than CamelCasing variables (as done in all other programming languages).
  3. This regular expression is looking for the string TEST_SEQUENCE followed by an equal sign.

    • The ^ anchors your regular expression to the start of the line. You don't want # The following sets TEST_SEQUENCE =... to be caught.
    • The \s* are there in case there are spaces or tabs in that string. TEST_SEQUENCE = Basic or TEST_SEQUENCE= Basic or TEST_SEQUENCE=Basic.
    • I then look for the string TEST_SEQUENCE followed by optional spaces followed by a =.
    • The (.*) captures the rest of the line (leaving out possible prefixed spaces. This is automatically put into the $1 variable.
  4. In your original example, you don't do return anything from your subroutine. I assume you want to return at least the value of Test Sequence, so I return that (if set). I use an if statement in case you're doing something else. However, the whole if could easily be return $test_sequence_value;. If $test_sequence_value isn't defined, it will return undefined, and you can test for that to see if it was found.

Upvotes: 0

Jens
Jens

Reputation: 69440

Try to use regexp:

my $variable;
if ($line =~ /TEST_SEQUENCE=(\w+)/){
  $variable = $1;
}

Upvotes: 1

Related Questions