pattern matching

J

josef hader

I am not too familiar with perl ;), so it may be a trivial problem...

I have to exchange in an input file containing
"parameter alpha=value; "
value into value1:
"parameter alpha=value1; "

I used to have it like this:
"parameter: alpha: value "
where the perl program (written by someone else) looked like

if ($zeile =~ m/alpha/ ){
my @eintr = split(/:/,$zeile);
$eintr[2]=value1;
print PARA_WRITE $eintr[0].":".$eintr[1].":".$eintr[2]."\n";
}

(in PARA_WRITE one writes into a file, $zeile is the line read in from
the file)
What do I have to change?

thanks!!
 
D

David Squire

josef said:
I am not too familiar with perl ;), so it may be a trivial problem...

I have to exchange in an input file containing
"parameter alpha=value; "
value into value1:
"parameter alpha=value1; "

I used to have it like this:
"parameter: alpha: value "
where the perl program (written by someone else) looked like

if ($zeile =~ m/alpha/ ){
my @eintr = split(/:/,$zeile);
$eintr[2]=value1;
print PARA_WRITE $eintr[0].":".$eintr[1].":".$eintr[2]."\n";
}

(in PARA_WRITE one writes into a file, $zeile is the line read in from
the file)
What do I have to change?

Please read the posting guidelines for this group. In particular, they
ask you to post a small, *complete*, script that illustrates your
question. Otherwise, it is very hard to know what you really want. For
example, do you want the format "parameter alpha=value;", or the
colon-separated version in your example.

As an example of why a complete script is wanted, consider your line above:

$eintr[2]=value1;

This will not compile if you start your script with 'use strict;' and
'use warnings', as is highly recommended. Do you really mean that value1
is a bare word??? I suspect that it is more likely to be a variable $value1.

A simple way to do this (assuming that I have correctly guessed what you
want) is:

----

#!/usr/bin/perl
use strict;
use warnings;

my $value1 = 10;
while (<DATA>) {
s/(\S+\s+\S+?=)([^;]+)/$1$value1/;
print;
}

__DATA__
parameter alpha=3;
frog cat=dog;

----

Output:
parameter alpha=10;
frog cat=10;

DS
 
J

josef hader

sorry for that.
what the script should achieve:
exchange in a file when it reads:
parameter reduced_v=10;
with e.g.
parameter reduced_v=15;
thus it should change the definition of reduced_v (indicated by
parameter ..= ..), but no other occurencies with reduced_v=....; which
follow later in the file.

here is the whole script:

#! /usr/bin/perl -w

use strict;
use warnings;
use diagnostics;

my $rd =
open(PARA_READ,"<"."solid_1_domain_isotropic_line_tension.fe");
my $rw =
open(PARA_WRITE,">".$dir."solid_1_domain_isotropic_line_tension.fe");

while (defined(my $zeile =<PARA_READ>)) {

#adapt reduced volume

if ($zeile =~ m/reduced_v/ ){
my @eintr = split(/:/,$zeile);
$eintr[2]=$red_vol[$ctr_red_vol];
print PARA_WRITE $eintr[0].":".$eintr[1].":".$eintr[2]."\n";
}
}
close(PARA_READ);
close(PARA_WRITE);
 
D

David Squire

josef said:
sorry for that.
what the script should achieve:
exchange in a file when it reads:
parameter reduced_v=10;
with e.g.
parameter reduced_v=15;
thus it should change the definition of reduced_v (indicated by
parameter ..= ..), but no other occurencies with reduced_v=....; which
follow later in the file.

here is the whole script:

#! /usr/bin/perl -w

use strict;
use warnings;
use diagnostics;

my $rd =
open(PARA_READ,"<"."solid_1_domain_isotropic_line_tension.fe");
my $rw =
open(PARA_WRITE,">".$dir."solid_1_domain_isotropic_line_tension.fe");

You should always check for the success of an open, and it is a good
idea to use the three argument version of open, e.g.

open PARA_WRITE, '>', $dir."solid_1_domain_isotropic_line_tension.fe" or
die "Couldn't open ".$dir."solid_1_domain_isotropic_line_tension.fe:
reason $!";
while (defined(my $zeile =<PARA_READ>)) {

#adapt reduced volume

if ($zeile =~ m/reduced_v/ ){
my @eintr = split(/:/,$zeile);
$eintr[2]=$red_vol[$ctr_red_vol];
print PARA_WRITE $eintr[0].":".$eintr[1].":".$eintr[2]."\n";
}
}
close(PARA_READ);
close(PARA_WRITE);

Have you even tried reading the perl documentation? You do not seem to
have made any attempt to solve the problem yourself. The paradigm here
is: you try, you post your attempt, we try to help.

Here is a script that should do what you want (assuming this should be
the first thing on the line, and allowing for variable white space):

----

#!/usr/bin/perl
use strict;
use warnings;

my $value1 = 15;
my $param_name = 'reduced_v';
while (<DATA>) {
s/(^\s*parameter\s+\Q$param_name\E\s*=\s*)([^;]+)/$1$value1/ if
(/reduced_v/);
print;
}

__DATA__
parameter alpha=3;
parameter reduced_v=10;
here's another use of reduced_v;
and another: reduced_v = reduced_v + 10;

----

Output:
parameter alpha=3;
parameter reduced_v=15;
here's another use of reduced_v;
and another: reduced_v = reduced_v + 10;


DS
 
D

David Squire

David Squire wrote:

Here is a script that should do what you want (assuming this should be
the first thing on the line, and allowing for variable white space):
....
s/(^\s*parameter\s+\Q$param_name\E\s*=\s*)([^;]+)/$1$value1/ if (/reduced_v/);
....

Sorry, that should have been:

s/(^\s*parameter\s+\Q$param_name\E\s*=\s*)([^;]+)/$1$value1/ if
/$param_name/;

DS
 
D

David Squire

David said:
David Squire wrote:

Here is a script that should do what you want (assuming this should be
the first thing on the line, and allowing for variable white space):
...
s/(^\s*parameter\s+\Q$param_name\E\s*=\s*)([^;]+)/$1$value1/ if
(/reduced_v/);
...

Sorry, that should have been:

s/(^\s*parameter\s+\Q$param_name\E\s*=\s*)([^;]+)/$1$value1/ if
/$param_name/;

Or indeed:

s/(^\s*parameter\s+\Q$param_name\E\s*=\s*)([^;]+)/$1$value1/ if
/\Q$param_name\E/;

:(

++$pedantry;
++$safeness;

:)
 
X

Xicheng Jia

David said:
josef said:
sorry for that.
what the script should achieve:
exchange in a file when it reads:
parameter reduced_v=10;
with e.g.
parameter reduced_v=15;
thus it should change the definition of reduced_v (indicated by
parameter ..= ..), but no other occurencies with reduced_v=....; which
follow later in the file.

here is the whole script:

#! /usr/bin/perl -w

use strict;
use warnings;
use diagnostics;

my $rd =
open(PARA_READ,"<"."solid_1_domain_isotropic_line_tension.fe");
my $rw =
open(PARA_WRITE,">".$dir."solid_1_domain_isotropic_line_tension.fe");

You should always check for the success of an open, and it is a good
idea to use the three argument version of open, e.g.

open PARA_WRITE, '>', $dir."solid_1_domain_isotropic_line_tension.fe" or
die "Couldn't open ".$dir."solid_1_domain_isotropic_line_tension.fe:
reason $!";
while (defined(my $zeile =<PARA_READ>)) {

#adapt reduced volume

if ($zeile =~ m/reduced_v/ ){
my @eintr = split(/:/,$zeile);
$eintr[2]=$red_vol[$ctr_red_vol];
print PARA_WRITE $eintr[0].":".$eintr[1].":".$eintr[2]."\n";
}
}
close(PARA_READ);
close(PARA_WRITE);

Have you even tried reading the perl documentation? You do not seem to
have made any attempt to solve the problem yourself. The paradigm here
is: you try, you post your attempt, we try to help.

Here is a script that should do what you want (assuming this should be
the first thing on the line, and allowing for variable white space):

----

#!/usr/bin/perl
use strict;
use warnings;

my $value1 = 15;
my $param_name = 'reduced_v';
while (<DATA>) {
s/(^\s*parameter\s+\Q$param_name\E\s*=\s*)([^;]+)/$1$value1/ if
(/reduced_v/);
print;
}

how about the following:

if ( $zeile =~ /parameter\s+\Q$param_name\s*=/) {
$zeile =~ s{[^=]*$}{$value1;\n};
print PARA_WRITE $zeile;
}

I guess the OP wants to print only lines matching $param_name.
(untested)

Xicheng
 
T

Tad McClellan

Are you Josef Hader or are you Gary Larson?

I am not too familiar with perl ;)


What have you done so far to fix that problem?

so it may be a trivial problem...

I have to exchange in an input file containing
"parameter alpha=value; "
value into value1:
"parameter alpha=value1; "


s/"parameter alpha=value; "/"parameter alpha=value1; "/;

I used to have it like this:
"parameter: alpha: value "
where the perl program (written by someone else) looked like

if ($zeile =~ m/alpha/ ){
my @eintr = split(/:/,$zeile);
$eintr[2]=value1;
print PARA_WRITE $eintr[0].":".$eintr[1].":".$eintr[2]."\n";
}


I doubt that that is your real code.

What part is it that you need help understanding?

Just be be sure I don't miss that one thing, I'll explain *all* of it:

if is a conditional flow control statement. $zeile is a scalar
variable, m/alpha/ is a regular expression match, =~ binds that
match to the string in the $zeile variable, my declares a lexical
variable, @eintr is an array, = is the assignment operator, split
is a function that splits strings into lists, $eintr[2] is
accessing the 3rd element in the @eintr array, I dunno what
the hell value1 is, print sends output, PARA_WRITE is a filehandle
that print sends the output to, $eintr[0] is accessing the 1st
element in the @eintr array, dot is the string concatenation
operator, $eintr[1] is accessing the 2nd element in the @eintr
array, $eintr[2] is accessing the 3rd element in the @eintr
array, and colons are colons.

Phew!

HTH

What do I have to change?


You have to change
"parameter alpha=value; "
value into
"parameter alpha=value1; "
just like you said.


Post a short and complete program that we can run that illustrates
your problem, and someone can surely help you solve your problem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,128
Latest member
ElwoodPhil
Top