perl : replace multiline text between two marker points
Hi there
I just wondered if someone could give me some perl advice
I have a bunch of text files used for a wiki that have common headings such as
Code:
---++ Title
blah
---++ Summary
blah
---++ Details
Here is the multiline
block
of text I
wish
to
replace that will
be different
in
every file
---++ More info
blah
So basically, All of the text between the "---++ Details" marker and the "---++ More info" marker I want to strip out and replace with a static multiline piece of text which i will put in a variable ...
Does anyone know of a quick and dirty way within perl of doing this, so far in my code i am passing the filename to the script for opening, I have create a 'here doc' style variable to contain my desired mutiline block of text and that is where my mind has gone blank ...
I guess i need a way of detecting the "---++ Details" line, deleteing everything after it up to and not including the "---++ More info" line and then putting the contents of $newtext into that space ?
$
$
$ cat -n f50
1 ---++ Title
2 blah
3
4 ---++ Summary
5 blah
6
7 ---++ Details
8 Here is the multiline
9 block
10 of text I
11 wish
12 to
13 replace that will
14 be different
15 in
16 every file
17
18 ---++ More info
19 blah
$
$
$ perl -lne 'BEGIN {$x=1; $str = "My multi-line\nstatic text\nover here"}
if (/^---\+\+ Details/) {print; $x=0}
elsif (/^---\+\+ More info/) {print $str; $x=1}
print if $x==1
' f50
---++ Title
blah---++ Summary
blah---++ Details
My multi-line
static text
over here
---++ More info
blah
$
$
$
---------- Post updated at 07:16 AM ---------- Previous update was at 05:12 AM ----------
Hi one further question if i may. I am trying to create a perl script out of this so that I can put all the files I wish to edit into an array and edit them all rather than running this from the command line
but how do i tell the little function youve provided about the file I want to edit so for example
Code:
#!/usr/bin/perl -w
use strict;
my @array = <i will populate this array with files names>
my $x;
my $str = <<EOF;
My new
multi-line
static text
EOF
foreach (@array) {
open FILE,"+>$_"
BEGIN { $x=1 };
if (/^---\+\+ Details/) {
print; $x=0
} elsif (/^---\+\+ More info/) {
print $str; $x=1
}
print if $x==1
close $_;
}
Ive clearly done that completely wrong as it doesnt work , but I cant seem to put your nice little function to use inside a script that passes my filenames in the array as the equivelant of the 'standard in' from your command line version?
creates backup files called "file1.bak", "file2.bak" and "file3.bak" for the original files "file1", "file2" and "file3" and then modifies them inline.
An example follows -
Code:
$$ # check the original files$$ cat -n file1 1 ---++ Title 2 FILE1 3 4 ---++ Summary 5 blah 6 7 ---++ Details 8 Here is the multiline 9 block 10 of text I 11 wish 12 to 13 replace that will 14 be different 15 in 16 every file 17 18 ---++ More info 19 blah$$ cat -n file2 1 ---++ Title 2 FILE2 3 4 ---++ Summary 5 blah 6 7 ---++ Details 8 Here is the multiline 9 block 10 of text I 11 wish 12 to 13 replace that will 14 be different 15 in 16 every file 17 18 ---++ More info 19 blah$$ cat -n file3 1 ---++ Title 2 FILE3 3 4 ---++ Summary 5 blah 6 7 ---++ Details 8 Here is the multiline 9 block 10 of text I 11 wish 12 to 13 replace that will 14 be different 15 in 16 every file 17 18 ---++ More info 19 blah$$ # run the Perl one-liner$$ perl -i.bak -pe 'BEGIN {undef $/; $x="My multi-line\nstatic text\nover here"} s/(---\+\+ Details\n).*?(\n---\+\+ More info)/$1$x$2/s ' file1 file2 file3$$ # now check the modified files$$ cat -n file1 1 ---++ Title 2 FILE1 3 4 ---++ Summary 5 blah 6 7 ---++ Details 8 My multi-line 9 static text 10 over here 11 ---++ More info 12 blah$$ cat -n file2 1 ---++ Title 2 FILE2 3 4 ---++ Summary 5 blah 6 7 ---++ Details 8 My multi-line 9 static text 10 over here 11 ---++ More info 12 blah$$ cat -n file3 1 ---++ Title 2 FILE3 3 4 ---++ Summary 5 blah 6 7 ---++ Details 8 My multi-line 9 static text 10 over here 11 ---++ More info 12 blah$$ # and see if the original files were backed up$$ cat -n file1.bak 1 ---++ Title 2 FILE1 3 4 ---++ Summary 5 blah 6 7 ---++ Details 8 Here is the multiline 9 block 10 of text I 11 wish 12 to 13 replace that will 14 be different 15 in 16 every file 17 18 ---++ More info 19 blah$$ cat -n file2.bak 1 ---++ Title 2 FILE2 3 4 ---++ Summary 5 blah 6 7 ---++ Details 8 Here is the multiline 9 block 10 of text I 11 wish 12 to 13 replace that will 14 be different 15 in 16 every file 17 18 ---++ More info 19 blah$$ cat -n file3.bak 1 ---++ Title 2 FILE3 3 4 ---++ Summary 5 blah 6 7 ---++ Details 8 Here is the multiline 9 block 10 of text I 11 wish 12 to 13 replace that will 14 be different 15 in 16 every file 17 18 ---++ More info 19 blah$$
You could use regular expressions while specifying the original files, and Perl takes care of resolving them, backing them up and editing them individually, e.g. in my case above, I could use -
Thanks Tyler, The situation unfortunately is that this will form part of a larger perl script that will run as part of a schedule hence the question on integrating it into a script as opposed to running it manually on the command line. The list of filenames to edit will be generated as part of another process and will be available to me to use within the same perl script as an @array
...this will form part of a larger perl script that will run as part of a schedule hence the question on integrating it into a script as opposed to running it manually on the command line. The list of filenames to edit will be generated as part of another process and will be available to me to use within the same perl script as an @array
Here's a Perl program for that case -
Code:
$
$ # The Perl program to modify multi-line text in multiple files
$
$ cat -n modify_multiline.pl
1 #!/usr/bin/perl -w
2 use strict;
3 my @files = qw (file1 file2 file3); # file list to modify
4 my $text = <<"EOF"; # multi-line static text
5 My multi-line
6 static text
7 over here
8 EOF
9 foreach my $old (@files) {
10 my $new = "$old.new";
11 open(OLD, "<", $old) or die "Can't open $old: $!";
12 open(NEW, ">", $new) or die "Can't open $new: $!";
13 my $on = 1; # set printing on at the outset
14 while (<OLD>) {
15 if (/^---\+\+ Details/) { # matched pattern starts
16 print NEW $_; # print this line
17 $on = 0; # set printing off
18 } elsif (/^---\+\+ More info/) { # matched pattern ends
19 print NEW $text; # print static text
20 $on = 1; # set printing on
21 }
22 print NEW $_ if $on; # print if printing on
23 }
24 close(OLD) or die "Can't close $old: $!";
25 close(NEW) or die "Can't close $new: $!";
26 rename($old, "$old.bak") or die "Can't rename $old to $old.bak: $!";
27 rename($new, $old) or die "Can't rename $new to $old: $!";
28 }
$
$ # Original files before modification
$
$ cat -n file1
1 ---++ Title
2 FILE1
3
4 ---++ Summary
5 blah
6
7 ---++ Details
8 Here is the multiline
9 block
10 of text I
11 wish
12 to
13 replace that will
14 be different
15 in
16 every file
17
18 ---++ More info
19 blah
$
$ cat -n file2
1 ---++ Title
2 FILE2
3
4 ---++ Summary
5 blah
6
7 ---++ Details
8 Here is the multiline
9 block
10 of text I
11 wish
12 to
13 replace that will
14 be different
15 in
16 every file
17
18 ---++ More info
19 blah
$
$ cat -n file3
1 ---++ Title
2 FILE3
3
4 ---++ Summary
5 blah
6
7 ---++ Details
8 Here is the multiline
9 block
10 of text I
11 wish
12 to
13 replace that will
14 be different
15 in
16 every file
17
18 ---++ More info
19 blah
$
$ # Now run the Perl program
$
$ perl modify_multiline.pl
$
$ # Check modified files
$
$ cat -n file1
1 ---++ Title
2 FILE1
3
4 ---++ Summary
5 blah
6
7 ---++ Details
8 My multi-line
9 static text
10 over here
11 ---++ More info
12 blah
$
$ cat -n file2
1 ---++ Title
2 FILE2
3
4 ---++ Summary
5 blah
6
7 ---++ Details
8 My multi-line
9 static text
10 over here
11 ---++ More info
12 blah
$
$ cat -n file3
1 ---++ Title
2 FILE3
3
4 ---++ Summary
5 blah
6
7 ---++ Details
8 My multi-line
9 static text
10 over here
11 ---++ More info
12 blah
$
$ # Check backup files
$
$ cat -n file1.bak
1 ---++ Title
2 FILE1
3
4 ---++ Summary
5 blah
6
7 ---++ Details
8 Here is the multiline
9 block
10 of text I
11 wish
12 to
13 replace that will
14 be different
15 in
16 every file
17
18 ---++ More info
19 blah
$
$ cat -n file2.bak
1 ---++ Title
2 FILE2
3
4 ---++ Summary
5 blah
6
7 ---++ Details
8 Here is the multiline
9 block
10 of text I
11 wish
12 to
13 replace that will
14 be different
15 in
16 every file
17
18 ---++ More info
19 blah
$
$ cat -n file3.bak
1 ---++ Title
2 FILE3
3
4 ---++ Summary
5 blah
6
7 ---++ Details
8 Here is the multiline
9 block
10 of text I
11 wish
12 to
13 replace that will
14 be different
15 in
16 every file
17
18 ---++ More info
19 blah
$
$
Hi
We have a database export file which needs to be formatted as below
InputCreate view ABC1 as Locking ABC1
for Access select * from PQR
Create view ABC2 as Locking
ABC2 for access
select * from PQR
Create view ABC3
as Locking ABC3
for
Access
select * from PQR
OutputCreate... (5 Replies)
Hi all
I have data files which contain data as shown below:
Line 5: FIDE
INST_DESC: DIAM Co Ltd/Japan => MAID Co Ltd/Japan
INST_NME: DIAM Co Ltd/Japan => MAID Co Ltd/Japan
Line 6: FIDE
INST_DESC: DIAM DL/Pimco US Bond Open Born in the USA => MAID DL/Pimco US Bond Open Born in the... (6 Replies)
Not quite a unix question but problem in a perl command. Taking a chance if someone knows about the error
cat 1
a b c d
perl -p -e 's/a/b/g' 1
b b c d
What is the problem here??
perl -p -i -e 's/a/b/g' 1
Can't remove 1: Text file busy, skipping file. (2 Replies)
Hello,
Consider that i have many files that have the below format:
file1
900 7777
1000 5 6 23 nnnnnnnnnnnnnnnnnn
1100 kkkkkkk
file2
900 1989
1000 5 3 10 kkkdfdfdffd
1100 kkkkkkk
What i would like to do is on every file to search the line that starts with... (4 Replies)
Hello guys,
I'm trying to replace the word "i.e." for "ie." in Vi but everytime I used the search tool for start looking for it (this is: /i.e.), it finds every word that contains the "i" and "e" word. I tried the following command:
:%s/i.e./ie./g
However, it doesn't work.
Any help... (2 Replies)
I've got this xml file
<file1>
some text here
</file1>
<file2>
some text here
</file2>
How do I change the text in element file1 to a sentence that I want, defined by variable $sentence. using ksh here. (2 Replies)
Hi,
I am a newbie to shell scripting and to Linux environment as well.
In my project I am trying to search for following text from the httpd.conf file
<Directory '/somedir/someinnerdir'>
AllowOverride All
</Directory>
and then remove this text and again rewrite the same text.
The... (1 Reply)
I have a data of the form
0.0117843924 0. 0. 0. 0.
0.011036017 0. 0. 0. 0.
0.0103351669 0. 0. 0. 0.
4839.41211 0. 0. 0. 0.
4532.08203 0. 0. 0. 0.
I would like to insert a couple of blank lines before the 4839 line, every time it appears. The numbers in the... (2 Replies)
I have a file that contains the following string.
connect odemgr/bank123@odsd
I am liiking to write a scrupt that will change the par of the string between the "/" and the "@" anyhelp qwould be greatly appriciated. (3 Replies)