By now the question has assumed form. I take it that you want to change the number in { } on a particular line in the file. The posted code got close and I’ll comment on basics and complete it.
Since we now find the number inside { } there is no need for the hard-coded $old_value. In order to identify the desired line you need to match the $old_parameter so the condition becomes if (/$old_parameter/). A comment on regex matching follows, related only to what is used in the code. Please read documentation and books for more.
Consider while (my $line = <$fh>). A line is read from the file via $fh by the diamond operator <> and assigned to a variable $line. If you leave out the variable and write only while (<$fh>) then the line is assigned to a special variable called $_. This variable is often used as a default in Perl. See General Variables.
To check whether a pattern is in a variable, to “match” it, we say $var =~ m/$patt/. This returns true or false in scalar context while in list context it returns the matches. See Extracting Matches. A pattern is best placed into a variable by $patt = qr(...). Our line is in $_ so we need $_ =~ m/$patt/, where m may be omitted. Regex also allows a shortcut, since it works by default on $_, and we may say /$patt/. Thus if (/.../).
Now consider substitution. To find a pattern and replace it we say $var =~ s/$patt/$repl/. This changes $var “in-place“, meaning that after that statement $var is changed. If the $patt wasn’t found in $var nothing happens to it. With our line in $_ we again need $_ instead of $var, but the same shortcut works and we can say s/$patt/$repl/.
Your code has this – but it doesn’t do anything with it. The result is never given by the program. An easy way is to print every line and the output can be redirected to a file. Or write lines to a file.
Now for the needed regex. You want a number inside of { }. According to the data you show it is the only such pattern in the line. Then this will do
s/ \{ \s* \d+ \s* \} /{$new_value}/x;
The /x allows us to use spaces for readibilty. (Otherwise they would be looked for in the string!) A digit is matched by \d, and + means all that come together, but at least one. In a123b it matches 123, in a12b3c it matches 12. The { and } are escaped since they have a special meaning in a regex. The \s* allows for any number of spaces, or for none.
The replacement side of the regex says to replace all that has been matched with {$new_value}. There we don’t have to escape {, }. If you need to capture (remember) what has been matched place the pattern in between (). Here you can say
s/ (\{ \s*) (\d+) (\s* \}) /$1$new_value$3/x;
and have the original spaces preserved. The first capture is stored in $1, the second in $2, etc. If the $new_value changes during the loop you can compute it before the substitution.
Please see the answer by Schwern and the technique offered in a comment by ikegami.
Then we only need to print the line. The full program
use warnings 'all';
use strict;
my $old_parameter="stack overflow version";
my $new_value = 20;
my $filename="input.txt";
open my $fh, "<", $filename or die "Can't open $filename: $!";
while ( <$fh> )
{
if (/$old_parameter/)
{
s/\{\s* (\d+) \s*\}/{$new_value}/x;
}
print;
}
The print; uses the same default, $_, and means print $_;. It is after the condition so that all lines are printed, changed or not. A few other errors have been fixed. An amusing one is the following: your $old_parameter has “stack overfolw version” (misspelled) so it never matches the line.
Finally, please read through perlretut, or better yet, through a nice chapter on regular expressions from a book or a tutorial that you are working with.
6
solved How to do multiple value replacement in a multiple line at one time