Your code isn't modifying the file because it's not writing to it; the substitution only affects the string in memory. That it has been read from a file is irrelevant at that time.
The easiest way to accomplish what you want is to use perl's -i switch; see perlrun for more.
| [reply] |
You are reading from the file, changing a variable in the program, but don't write the changes back out. Typically, we open one file, make changes in memory, and then write out to a second file. At this point, we could overwrite the old with the new, or preserve both. See open.
Follow the link in the link! That is where I meant to go in the first place.
| [reply] |
This a possible approach (untested code):
use strict;
use warnings;
my $infile = "filename.txt";
my $outfile = "filename.out";
open my $IN, "<", $infile or die "Could not open file $infile : $!";
open my $OUT, ">", $outfile or die "Could not open file $outfile : $!"
+;
my $step_num = 0;
while (<$IN>) {
if (/-----------step [\d]\./){
$step_num ++;
s/-----------step \d\./-----------step $_\.$step_num/;
}
print $_ $OUT;
}
close $IN;
close $OUT;
Once you are happy with the content of the filename.out file, you can add code to delete or rename in input file and rename your output file to the original source file, if needed (or to rename the input file before hand and write directly to an output file having the name of the input file, if you prefer).
Although there are some work-around solutions, in general you can't read from and write to the same free-format file, and this is essentially true in almost any programming language.
The two main solutions are the following:
1. open the input file, load it all into memory (e.g. in an array of lines), close the file, modify its content in memory, open the same file in write mode (which will clutter its original content), and print the result into it (this is basically what's going on behind the scenes when you open a text file with your favorite editor or with a word processor);
2. Read the file and write to another file (as suggested in my code above), and do the necessary house cleaning (renaming the files) afterward or possibly before (this is what the -i command-line option suggested by AppleFritter if essentially doing behind the scene).
There are a few "more advanced" solutions, such as using tieed variables (i.e. doing even more complicated things behind the scene), but I would suggest that you stay with either of the two simple solutions described above for the time being.
As an additional point, please note that I made a few other changes to your code, adding the use strict; use warnings; pragmas (you should always have them, except possibly for one-liners), and changing the syntax for opening a file to the "3-argument" syntax, this is not absolutely necessary, but this is considered to be good practice nowadays. This "new" syntax was introduced, I believe, with Perl 5.6, so that's more than ten years ago.
| [reply] [d/l] [select] |
... introduced ... with Perl 5.6 ... more than ten years ago.
Indeed, perlhist sez the release date for 5.6.0 was "2000-Mar-22", so more (by one day as I post this in my TZ) than fifteen years ago!
What were you doing then?
Give a man a fish: <%-(-(-(-<
| [reply] [d/l] |
Time flies like an arrow. From pure memory, I thought 5.6 was relased 12 or 13 years ago, I had written "more than 10" to be on the safe side of things. Thanks ++, I now will remember I can write "more than 15 years ago" new time I want to speak about that.
| [reply] |
I'm not sure exactly what your data looks like. How many lines are then to be replaced? Do the step numbers change and if they do, how? So i came up with a candidate data file that looks like this:
-----------step 1.
-----------step 1.
-----------step 1.
-----------step 2.
-----------step 1.
-----------step 1.
-----------step 1.
-----------step 2.
-----------step 2.
-----------step 2.
-----------step 3.
-----------step 3.
-----------step 2.
-----------step 2.
-----------step 3.
-----------step 3.
The following one liner will transform the data into hopefully something that is very close to want you want.
perl -pi -e's/(-----------step\s+)(\d+)\./$h{$2}||=$2;$h{$2}+=.1;$1.$h
+{$2}/ge' foo.txt; cat foo.txt
-----------step 1.1
-----------step 1.2
-----------step 1.3
-----------step 2.1
-----------step 1.4
-----------step 1.5
-----------step 1.6
-----------step 2.2
-----------step 2.3
-----------step 2.4
-----------step 3.1
-----------step 3.2
-----------step 2.5
-----------step 2.6
-----------step 3.3
-----------step 3.4
If not, then please feel free to post more examples of the data you are working with.
| [reply] [d/l] |